我有:

ArrayList<SubwordInfo> subwordInfoList-我的数据-SubwordInfo对象的列表。

ListView lvSubwords-用于显示我的数据的ListView

SubwordListAdapter subwordListAdapter-我自己的subwordInfoListlvSubwords之间的适配器(基于BaseAdapter)。

在某个时候,我想做一个简单的事情:


更新subwordInfoList中的数据项。
更新lvSubwords中相应子视图的外观。
在此子视图上定位lvSubwords
在此子视图上运行动画。


步骤1-3工作正常。但是第4步是一个问题,因为我无法以正确的方式访问子视图。我的子视图错误或为空。

有代码:

SubwordInfo si;
...
si=subwordInfoList.get(subwordNo);

<updating si>

subwordListAdapter.notifyDataSetChanged();  //Notify for update - successfull
lvSubwords.setSelection(subwordNo);         //Positionize - successfull


之后,我尝试访问对应于si的子视图。

我试图这样做:

View view = lvSubwords.getChildAt(subwordNo-lvSubwords.getFirstVisiblePosition());
if (view!=null)
    view.startAnimation(animHighlight);


有时它起作用,有时却不起作用(view == NULL)。有时,视图是错误的视图。

我也尝试使用视图标签:

View view = lvSubwords.findViewWithTag(si);
if (view!=null)
    view.startAnimation(animHighlight);


标签是在适配器的getView中分配的:

@Override
public View getView(int arg0, View arg1, ViewGroup arg2)
{
    View view = arg1;
    if (view == null)
      view = lInflater.inflate(R.layout.subword_element, arg2, false);

    SubwordInfo si = getSubwordInfo(arg0);

    ...

    view.setTag(si);//Assigning tags

    return view;
}


仅在lvSubwords.getFirstVisiblePosition()subwordListAdapter.notifyDataSetChanged()调用之前lvSubwords.setSelection为0的情况下才有效。否则,视图为null。

另外,我发现lvSubwords.getFirstVisiblePosition()在调用lvSubwords.setSelection之前和之后返回相同的值。

因此,在我看来,调用ListView和ListView的subwordListAdapter.notifyDataSetChanged()lvSubwords.setSelection子视图后,不会立即更新。他们将在以后的某个时间更新。如何捕捉这一刻并获得理想的动画子视图?

最佳答案

自从我做完以来有点,但是我相信你有点落后。 SetSelection应该将适配器的位置对准ListView的顶部。这意味着,只要始终在索引0处抓住孩子,就可以了。

另外,是setSelection不会立即发生。它会解雇事情,直到一段时间后才能完成。我在不久前遇到了类似的问题,我想出的唯一解决方案是postDelay使用您要执行的操作来运行。

lvSubwords.setSelection(subwordNo);
lvSubwords.postDelayed(new Runnable() {
    @Override
    public void run() {
        //Get View and start animation
    }
}, 66);


您可能需要等待多长时间。

10-08 09:20