ListAdapter.getView和ListView.getChildAt之间的区别

时间:2013-03-27 13:18:51

标签: java android

我的应用程序的UI有一个ListView,用于显示推文的时间线,并设置OnItemLongClickListener以显示带有多个按钮的另一个视图(“回复”,“转推”,“收藏”等)。在我的适配器的getView()方法中。

我想要什么:在我的测试项目中,我想通过长时间点击时间轴中的第一项,然后点击其中一个按钮来测试此功能。

代码部分如下所示:

timelineList.getChildAt(0).performLongClick();
favoriteBtn = (ToggleButton)timelineList.getAdapter().getView(0, null, timelineList).findViewById(cse.ust.twittermap.R.id.favorite);
favoriteBtn.performClick();
favoriteBtn.performClick();
timelineList.getChildAt(0).performLongClick();

这有效但当我尝试将第二行更改为:

timelineList.getChildAt(0).findViewById(cse.ust.twittermap.R.id.favorite);

测试项目抛出NullPointer异常,因为findViewById()返回 null

我的问题ListAdapter#getView()ListView#getChildAt()之间有什么区别?

它们似乎都可以返回对列表中项目视图的引用,但显然它们之间应该存在一些差异。我还想弄清楚为什么第二行中的getChildAt()方法无法通过Ids查找视图。

1 个答案:

答案 0 :(得分:1)

getChildAt不是ListView特有的方法。它是为每个ViewGroup(可以有孩子的视图)实现的。

创建ListView后,它没有子女。调用其适配器的getView方法不会改变这一事实,它不会添加任何子项。

只有当您的活动的内容得到衡量和布局时,ListView才会重复调用其适配器的getView方法并将返回的Views添加到自己的列表中,从而开始创建子视图孩子的。只有在那之后,ListView.getChildAt(x)才能返回一些非空值。

ListAdapter.getView方法代表ListView / GridView /等返回全新的Views(或只返回已回收的View)。您的代码永远不应该调用ListAdapter.getView本身(除非您进行单元测试)。

ListView.getChildAt会返回已创建的View(由ListAdapter.getView代表ListView创建的早期版本)注意您的ListAdpater可能会定义许多列表项(由getCount返回的值),但托管适配器的ListView将永远不会有比在屏幕上任何给定时间可见的更多子项。即您的ListAdapter可能会处理1000个列表项,但您的ListView永远不会超过6个子Views(当然,取决于屏幕大小和listview-item)。