0

所以我有这个ListView与自定义适配器,允许我“选择”项目点击项目。 现在列表中的每一行都有一个ImageView,当相应的项目被选中时,其Drawable I会变成“选定”图像。在我的棒棒糖设备上工作得很好。查看回到ListView与AnimationDrawable

我构建可绘制列表中的适配器的构造现在

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只要选择一种观点认为,应发挥(它是一个单 - 选择模式btw)。

视图在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对所有的列表项“全球性”的状态更新。因此,在构造函数中启动一次动画应该让动画始终播放每个列表项。

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

这里的问题是: 当我选择一个不同的列表项,而动画播放(单稳= false),则新选择项目的动画将如果低于老项目的位置,但如果它不玩了玩高于列表中的旧项目位置。 因此,我选择第一个项目。动画播放。第二项选择,动画播放。第三选择,动画玩....第十项选择,动画播放。在另一个方向,这是行不通的。如果我有第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调用中保存drawable的(昂贵的)实例化?

问题:为什么?如何正确设置动画?从每个新动画开始的资源中获取动画是否聪明(可能不是)?如何做到这一点?

回答

1

这是为什么? 每当播放动画时,场景后面会生成一个线程并将值应用于目标对象。此线程已同步,因此只有一个进程可以在时间输入。因此,您已为每个视图创建单独的动画对象。

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

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

+0

到目前为止感谢。但是,为什么动画会在当前选定项目下选择的列表项目播放? – mad

+0

因为每次你与listView交互。调用适配器的notifyDataSetChanged()方法以确保每个数据都按照新数据集绘制。这意味着调用适配器中每个数据集值的getView方法,这些值在设备屏幕上可见,并且您已编码的适配器为所选项目设置动画。因此,每次listView刷新其项目时,所有可见视图都会重绘。这是当您在listView中选择另一个项目时选定项目生成动画的原因。 – chandil03