有时listView.getChildAt(int index)返回NULL(Android)

时间:2012-04-25 15:31:58

标签: android view android-listview

我有一个带有自定义适配器的listView。当某些事情发生时(点击一个孩子)我会做一些计算并修改子视图。如果某些条件已经满足,则应修改与被点击的孩子无关的其他孩子。

这有时会起作用,但有时会失败,DDMS会说视图为空......

让我告诉你代码:

        if(invalidaEste != -1)
        {
            try
            {
                View v = lv_data.getChildAt(invalidaEste);
                if( v== null)
                {
                    Log.e("MY_LOG", "SIZE " + lv_data.getCount());
                    Log.e("MY_LOG", "IS_NULL " + String.valueOf(invalidaEste)); 
                }

                if(invalidaEste >= lv_data.getFirstVisiblePosition() &&
                   invalidaEste <= lv_data.getLastVisiblePosition())
                {
                    RelacionFacturaPago rpf = (RelacionFacturaPago)lv_data.getAdapter().getItem(invalidaEste);
                    TextView tv = (TextView)v.findViewById(R.id.tv_pendiente);
                    tv.setText(Formato.double2Screen(rpf.getPorPagar()));
                }
            }
            catch (Exception e)
            {
                Log.e("MY_LOG", "FAIL");
                Log.e("MY_LOG", String.valueOf(invalidaEste));
            }

        }

invalidaEste 是我要修改的视图。 当 v为null 时,我会记录索引以检查它是否正常。始终小于或等于listView.getCount()

为什么会这样?

更多数据:代码位于AnimationListener侦听器的onAnimationStart(动画动画)内。

4 个答案:

答案 0 :(得分:9)

由于视图回收,listView.getChildAt()只会返回其正在显示的位置的视图,也可能会返回一个视图。也许如果您分享更多代码,我们可以帮助您找出如何最好地解决问题。

答案 1 :(得分:4)

Dmon和Azertiti都是正确的......一旦你的列表滚动,你就会发现自己陷入困境。如果视图不可见,则它不存在(即已被Android回收)。滚动后,您将重新构建视图。

做这样的事情应该有效:

View view;

int nFirstPos = lv_data.getFirstVisiblePosition();
int nWantedPos = invalidaEste - nFirstPos;

if ((nWantedPos >= 0) && (nWantedPos <= lv_data.getChildCount())
{
 view = lv_data.getChildAt(nWantedPos);
 if (view == null)
  return;
 // else we have the view we want
}

答案 2 :(得分:1)

如果该孩子在屏幕上不可见,则表示没有View for it。我相信这不是你的工作案例。

一个好的做法是更改列表适配器后面的数据,并在适配器上调用notifyDataSetChanged()。这将通知适配器已更改的列表并再次绘制视图。

如果你真的想手动更新视图,我想唯一的解决办法就是在某个地方保留新值并等待View变为可见。此时您有一个有效的参考,可以进行更新。

答案 3 :(得分:1)

当我需要进入Listview的有效位置时,我用一行代码测试它。这是你的变量用作一个例子。其中lv_data是ListView,tv是你的TextView。

if ( lv_data.getChildAt(lv_data.getPositionForView(tv)) != null) {
    int position = lv_data.getPositionForView(tv);
}