1

My app's UI has a ListView to show the timeline of tweets and setup an OnItemLongClickListener to show another view with several buttons ("Reply", "Retweet", "Favorite", etc.). inside my Adapter's getView() method.

What I want: In my test project, I want to test this feature by performing a long click on the first item in the timeline and then performing a click on one of the buttons.

The part of code looks like below:

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();

This works but when I try to change the second line into:

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

The test project throws a NullPointer exception, because findViewById() return null.

My Question: What is the difference between ListAdapter#getView() and ListView#getChildAt()?

It seems both of them can return a reference to an item view in the list, but clearly there should be some differences between them. I also want to figure out why the getChildAt() method in the second line fails in finding views by Ids.

4

1 回答 1

2

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

创建ListView时,它没有子级。调用它的适配器的getView方法并不会改变这个事实,它不会添加任何孩子。

只有当您的 Activity 的内容被测量和布局时,它才会通过重复调用其适配器的方法并将返回的内容添加到它自己的子列表中来ListView开始创建子视图。只有在那之后,才能返回一些非空值。getViewViewsListView.getChildAt(x)

该方法代表 ListView/GridView/etcListAdapter.getView返回全新的Views(或仅返回回收的)。View您的代码不应该调用ListAdapter.getView自己(除非您进行单元测试)。

ListView.getChildAt返回一个已经创建的View(由ListAdapter.getView代表 较早创建的ListView)请注意,您ListAdpater可以定义许多列表项(由 返回的值getCount),但ListView托管适配器的子项永远不会超过在屏幕上任何给定时间可见的子项. 即您ListAdapter可以处理 1000 个列表项,但您的ListView孩子永远不会超过 6 个Views(当然,取决于屏幕的大小和列表视图项)。

于 2013-03-27T13:44:44.730 回答