我的应用程序的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查找视图。
答案 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)。