Android 同时为所有列表视图项设置动画

Posted

技术标签:

【中文标题】Android 同时为所有列表视图项设置动画【英文标题】:Android animate all listview items simultaneously 【发布时间】:2013-06-07 04:24:17 【问题描述】:

我想在所有列表视图项上实现同步动画以使其进入编辑模式。这是与我想要的效果相同的效果:http://youtu.be/cFSRusFkI_I?t=2m6s我的列表项布局代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_content"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:padding="4dp" >

    <CheckBox
        android:id="@+id/checkbox"
        android:layout_
        android:layout_
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:visibility="invisible" />

    <TextView
        android:id="@+id/nameTextView"
        android:layout_
        android:layout_
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:textSize="16sp"
        android:textStyle="bold" />

    <ImageView
        android:layout_
        android:layout_
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:paddingRight="5dip"
        android:src="@drawable/right_arrow" />

</RelativeLayout>

在用户单击 actionBar 中的按钮后,我想动画滑动复选框从左到右滑动,并带有适当的 textview 动画,为复选框腾出空间。我故意让复选框不可见,以测量其动画宽度。我用于动画复选框的方法(隐藏或显示,取决于状态参数):

public void setListHandlesVisibleState(boolean state) 
    AnimatorSet as = new AnimatorSet();
    int childCount = mListView.getChildCount();
    ArrayList<Animator> list = new ArrayList<Animator>();
    for (int i = 0; i<childCount; ++i) 
        CheckBox v = (CheckBox) mListView.getChildAt(i).findViewById(
                R.id.checkbox);
        TextView tv = (TextView) mListView.getChildAt(i).findViewById(
                R.id.nameTextView);
        if (state) 
            list.add(ObjectAnimator.ofFloat(v, "x", -v.getWidth(),
                    v.getLeft()));
            list.add(ObjectAnimator.ofFloat(v, "alpha", 0, 1));
            list.add(ObjectAnimator.ofFloat(tv, "x", tv.getLeft(),
                    (float) (v.getWidth() * 0.9)));
         else 
            list.add(ObjectAnimator.ofFloat(v, "x", v.getLeft(),
                    -v.getWidth()));
            list.add(ObjectAnimator.ofFloat(v, "alpha", 1, 0));
            list.add(ObjectAnimator.ofFloat(tv, "x",
                    (float) (v.getWidth() * 0.9), tv.getLeft()));
        
    
    as.addListener(this);
    as.playTogether(list);
    as.setDuration(200);
    as.start();

@Override
public void onAnimationEnd(Animator animation) 
    mAdapter.notifyDataSetChanged();

当列表视图短于一屏时(没有视图重用)动画看起来很完美并且非常流畅。当列表视图较长时,似乎某些列表视图项尚未创建,因此没有动画。我尝试在适配器中创建视图缓存并使用这些视图,而不是在适配器 getView 方法中使用 convertView,并在该缓存中包含的视图上播放动画。我还注意到,所有可重用视图都是在创建列表视图时创建的(当我滚动列表视图时,转换视图总是!= null)。

【问题讨论】:

我也想实现像你这样的东西,你能把整个代码贴在这里或者给我链接,以便我可以帮助你,我也可以使用那个代码 【参考方案1】:

查看this DevBytes video 了解动画ListViews

解决方案是使用StableArrayAdapter(直接链接到代码)。这可以防止 View 对象在您执行动画时从您下方回收。

private class StableArrayAdapter extends ArrayAdapter<String> 

    HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();

    public StableArrayAdapter(Context context, int textViewResourceId,
            List<String> objects) 
        super(context, textViewResourceId, objects);
        for (int i = 0; i < objects.size(); ++i) 
            mIdMap.put(objects.get(i), i);
        
    

    @Override
    public long getItemId(int position) 
        String item = getItem(position);
        return mIdMap.get(item);
    

    @Override
    public boolean hasStableIds() 
        return true;
    


您可能还会发现this video 很有帮助。

【讨论】:

以上是关于Android 同时为所有列表视图项设置动画的主要内容,如果未能解决你的问题,请参考以下文章

列表视图项之间的 Flutter Hero 类似动画

Android:将列表视图项设置为“选定”(突出显示)

避免在 Android 中将视图设置为 setTag 的值

Android - 自定义列表视图项始终位于左侧

如何在适配器类中的列表视图项上获取动画?

单击列表视图项时检索的值