ListView getChildAt为可见的子项返回null

我从listview / getChildAt方法得到一些奇怪的行为。

我有一个HashSet iconsToUpdate,在数据库中已被更改的图标。 我想遍历可见的行,看看是否有任何图标需要更新,以反映新的图标。 我不需要testing当前不在视图中的图标,因为它们在渲染时将被正确绘制。

我的问题是,当它看起来不应该getChildAt返回null。 我知道getChildAt只能返回当前可见的视图,但是对于某些可见行,它返回null。

这是我的代码遍历可见的行:

Logger.debug("First visible index: " + f_listView.getFirstVisiblePosition()); Logger.debug("Last visible index: " + f_listView.getLastVisiblePosition()); for (int i = f_listView.getFirstVisiblePosition(); i <= f_listView.getLastVisiblePosition(); i++) { String tag = "asdf"; // Remove when bug is fixed. if (f_listView == null) { Logger.debug("f_listView is null"); } else if (f_listView.getChildAt(i) == null) { Logger.debug("Child at index " + i + " is null"); } else { tag = (String) f_listView.getChildAt(i).getTag(); Logger.debug("Successful at index " + i + ", tag is: " + tag); } if (iconsToUpdate.contains(tag)) { setIcon(i, f_aim.getInHouseIcon(tag)); } } 

以下是对应于此循环运行的日志:

 D/...: First visible index: 3 D/...: Last visible index: 8 D/...: Successful at index 3, tag is: ... D/...: Successful at index 4, tag is: ... D/...: Successful at index 5, tag is: ... D/...: Child at index 6 is null D/...: Child at index 7 is null D/...: Child at index 8 is null 

应该指出,第一个和最后一个可见的索引正在正确报告,因为我正在查看第3-8行,当我运行这个。 第6,第7,第8行正在渲染。 他们如何显示,如果他们是空的?

另外,我不知道这是否重要,但是当我在列表视图的顶部时,第5行是最后一个可见行。

任何信息,为什么这些行被返回为null将不胜感激。

谢谢!

listView.getChildAt(i)的作品,其中0是第一个可见行,(n-1)是最后一个可见行(其中n是你看到的可见视图的数量)。

get last / first visible返回dataAdapter中的位置。 所以,当你从第3个位置开始,看起来像6个可见的视图,那么在6-8位置获得空位。

在你的例子getChildAt(0)将返回位置3.我通常做的是将位置存储在我的意见,所以我可以稍后查找我的dataAdapter,如果我需要值。

我认为你的for循环应该是这样的:

 for (int i = 0; i <= f_listView.getLastVisiblePosition() - f_listView.getFirstVisiblePosition(); i++) 

希望这可以帮助。

尝试

 f_listView.getChildAt(positionOfChildYouWantGet - f_listView.getFirstVisiblePosition()); 

当您调用listView1.getLastVisiblePosition()listView1.getFirstVisiblePosition()listview将返回在listview中部分可见的项目的位置。 例如,第一个项目可能是一半可见的,而最后一个项目可能是一半可见的。 在这种情况下,即使您可以在列表视图中看到该项目的一部分,但该适配器尚未为该项目调用getView()函数,因此该项目仍被视为null。

在我的情况下,我有一个listView和第一项是完全可见的,但是当我做getFirstVisiblePosition()结果是1!

当我滚动,使第一个项目一半可见时,它变得更奇怪,那么我的getView显示getFirstVisiblePosition()是0。

这我的代码:

 public View getView(final int position, View convertView, final ViewGroup parent) { row = convertView; final AtomPaymentHolder holder = new AtomPaymentHolder(); LayoutInflater inflater = ((Activity) context).getLayoutInflater(); row = inflater.inflate(layoutResourceId, parent, false); row.setTag(items.get(position)); holder.songitem = items.get(position); final int firstPosition = MainActivity.listviewSong.getFirstVisiblePosition() - MainActivity.listviewSong.getHeaderViewsCount(); final int lastPosition = MainActivity.listviewSong.getLastVisiblePosition(); if(MusicService.indexService>= firstPosition && MusicService.indexService<= lastPosition){ MainActivity.listviewSong.getChildAt(MusicService.indexService-firstPosition).setBackgroundColor(getContext().getResources().getColor(R.color.pressed_color)); } 

(当我select下一个项目,并滚动,它运作良好)

也许是部分可见的。 但是,当getView()试图回收视图时,它将获得完全可见的视图,而其他视图则将它们视为null。 例如,如果您滚动列表,顶部项目部分可见,底部部分可见,所以这些是空值,但你仍然看到它们。

我尝试了OnListItemClickListener(),但失败了。 最后,我对自定义的listview适配器做了一些修改。 在getView()中,我将clickListener应用于我经常添加到列表中的项目。 在那里做所有必要的function。 这里是我的代码,我在列表中添加图像视图ñ所以在ImageView上应用侦听器。

我认为这将有助于那些想要改变特定列表项目被选中时的颜色。 去吧..

在定制的适配器的getView()中// ——————————— code ——- ———————————–



LayoutInflater inflater =(LayoutInflater)上下文
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View rowView = inflater.inflate(R.layout.icon_image_layout, parent, false); ImageView imageView = (ImageView) rowView.findViewById(R.id.Icon_ImageView); imageView.setClickable(true); final int pos=position; imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub // TODO Auto-generated method stub try{ if(previous_view!=null) previous_view.setBackgroundColor(Color.WHITE); }catch (Exception e) { System.out.println("Exception Occurs Previous View"); } v.setBackgroundColor(Color.RED); MainActivity.imageView.setImageResource(MainActivity.Image_Name[pos]); previous_view=v; return false; } });

是不是因为你在说?

 f_listView.getChildAt(i) 

你应该在这个位置找回物品?

 f_listView.getItemAtPosition(i)