0

所以我有一个带有自定义适配器的 ListView,它允许我在项目点击时“选择”一个项目。Now every row of the list has an ImageView whose Drawable I change to a "selected" image when the respective item is selected. 在我的棒棒糖设备上工作正常。

我在列表适配器的构造函数中构造了 Drawables

public DoubleRowSelectableArrayAdapter(Context context, int resource2, List<Recording> recordings) {
    super(context, resource2, recordings);

    idle = ContextCompat.getDrawable(context,R.drawable.idleicon);
    animation = (AnimationDrawable) ContextCompat.getDrawable(context, R.drawable.animation);
}

现在,如您所见,“选定”项目是一个 AnimationDrawable,只要选择一个视图就会播放(顺便说一句,它是单选模式)。

视图在 getView 方法中更新

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
        convertView = layoutInflater.inflate(resource, null);
    }

    if (position == selection) {
        Log.d("getView", "selection = position");
        convertView.setSelected(true);
        convertView.setPressed(true);

        //get the imageview from the current row
        final ImageView pic = ((ImageView) convertView.findViewById(R.id.iconview));
        pic.setImageDrawable(animation);
    }
    else{
        Log.d("getView","else");
        convertView.setSelected(false);
        convertView.setPressed(false);

        //set idle icon
        ((ImageView) convertView.findViewById(R.id.iconview)).setImageDrawable(idle);
    }

我会假设 AnimationDrawable 对所有列表项都有一个“全局”状态。因此,在构造函数中启动一次动画应该让动画一直播放,对于每个列表项。

我设法为每个项目播放动画,例如通过在构造函数中启动它或在 getView 方法中使用 post() 调用。但是,我省略了那部分代码,因为我想专注于稍微不同的事情。

这是问题: 当我在播放动画时选择不同的列表项(oneshot = false),如果新选择的项目的动画低于旧项目的位置,则将播放但如果它高于旧项目的位置,则不会播放名单。所以,我选择了第一项。动画播放。选择第二项,动画播放。选中第三项,播放动画....选中第 10 项,播放动画。在另一个方向,这是行不通的。如果我播放第 10 个项目的动画并选择位置 1-9 的项目之一,则根本不会播放动画。在播放新动画之前,我必须等待正在运行的动画结束。

如果每次调用 getView 时我都从资源中获取 Drawable,这种行为就会发生变化——那么它工作得非常好。所以在getView

AnimationDrawable d = (AnimationDrawable) getContext().getResources().getDrawable(R.drawable.animation);
pic.setImageDrawable(d);
d.start(); //or by post() call, etc. -- however working.

我的猜测是,这与列表中的视图回收有关。我应该怎么做才能在每次 getView 调用中从资源中保存可绘制对象的(昂贵的?)实例化?

问题:为什么会这样?如何正确设置动画?为每个新动画开始(可能不是)从资源中获取可绘制动画是否聪明?怎么做才对?

4

1 回答 1

1

这是为什么? 每当播放动画时,都会在幕后生成一个线程并将值应用于目标对象。该线程是同步的,因此一次只能有一个进程进入。因此,您为每个视图创建了单独的动画对象。

如何正确设置动画?我应该怎么做才能在每次 getView 调用中从资源中保存可绘制对象的(昂贵的?)实例化?为每个新动画开始(可能不是)从资源中获取可绘制动画是否聪明?怎么做才对? 你做得对,你必须在每个 getview() 调用中创建 animationDrawable 。如果您想摆脱为视图创建多次可绘制对象(昂贵的任务),请将 animationDrawable 设置为标签并在每次 getView 调用时检索它,如果它为空则重新初始化。

如果不让我知道,我希望你能得到你的答案。

于 2015-12-29T13:01:49.617 回答