5

我有一个带有自定义适配器的 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 为空时,我记录索引以检查它是否正常。总是小于或等于 listView.getCount()

为什么会这样?

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

4

4 回答 4

9

Because of view recycling, listView.getChildAt() will only return a view for the positions it is displaying, and maybe one more. Maybe if you share more of your code we can help you figure out how to best tackle the problem.

于 2012-04-25T15:37:51.820 回答
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
}
于 2012-04-25T18:36:27.900 回答
1

If that child is not visible on screen it means there is no View for it. I believe this is your not working case.

A good practice is to change the data behind your list adapter and call notifyDataSetChanged() on the adapter. This will inform the list the adapter has changed and paint again the views.

If you really want to manually update the view I guess the only solution is to retain the new values somewhere and wait until the View becomes visible. At that point you have a valid reference and can do the updates.

于 2012-04-25T15:38:37.007 回答
1

当我需要进入 Listview 的有效位置时,我会使用一行代码对其进行测试。这是用作示例的变量。其中 lv_data 是 ListView,tv 是您的 TextView。

if ( lv_data.getChildAt(lv_data.getPositionForView(tv)) != null) {
    int position = lv_data.getPositionForView(tv);
}
于 2015-09-15T21:00:13.593 回答