Android - 调用Adapter.notifyDataSetChanged和ListView.setSelection后访问ListView中的View

时间:2015-01-06 00:13:53

标签: android listview view baseadapter notifydatasetchanged

我有:

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

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

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

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

  1. 更新subwordInfoList
  2. 中的数据项
  3. 更新lvSubwords中相应子视图的外观。
  4. 在此子视图上定位lvSubwords
  5. 在此子视图上运行动画。
  6. 步骤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()在致电lvSubwords.setSelection之前和之后返回相同的值。

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

1 个答案:

答案 0 :(得分:1)

自从我做完这件事之后就有点过了,但我相信你有点倒退了。 SetSelection应该将给定的适配器位置对齐到ListView的顶部。这意味着,你应该没事,总是抓住指数为0的孩子。

此外,是setSelection不会立即发生。它会解开,直到一段时间后才能完成。我在很久以前遇到过类似的问题,我能想到的唯一解决办法就是postDelay可以运行你想要的行动。

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

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