Android - 在调用 Adapter.notifyDataSetChanged 和 ListView.setSelection 后访问 ListView 中的视图

Android - Accessing View in ListView after call Adapter.notifyDataSetChanged and ListView.setSelection

我有:

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

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

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

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

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

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

有代码:

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 时才有效。否则,视图为空。

此外,我发现 lvSubwords.getFirstVisiblePosition() returns 调用前后的值相同 lvSubwords.setSelection

所以,在我看来,调用 ListView 的 subwordListAdapter.notifyDataSetChanged()lvSubwords.setSelection 子视图后,ListView 本身不会立即更新。他们会在稍后更新。我怎样才能抓住这一刻并获得我想要的动画子视图?

自从我完成此操作以来已经有一段时间了,但我相信你已经有点倒退了。 SetSelection 应该对齐 ListView 顶部给出的任何适配器位置。这意味着,你应该总是抓住索引 0 处的 child。

此外,是的 setSelection 不会立即发生。它会开火,直到一段时间后才结束。我 运行 很久以前就遇到过类似的问题,我能想到的唯一解决方案是 postDelay 一个包含你想要完成的操作的可运行对象。

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

您可能需要考虑等待的时间。