Android ListView.setOnItemClickListener NullPointerException当有更多项目然后屏幕可以容纳

时间:2011-10-09 03:53:35

标签: android android-listview

当此ListView有更多项目时,可以在屏幕上显示(您必须滚动查看其他项目)并选择其中一项我得到NullPointerException

以下是代码:

studentList = (ListView)findViewById(R.id.studentListView);
getAllStudents();
studentList.setOnItemClickListener(new OnItemClickListener(){
     @Override
     public void onItemClick(AdapterView<?> a, View v, int position, long id) {

        for (int i = 0; i < studentList.getCount(); i++){

                if (i == position){
                    studentList.getChildAt(i).setBackgroundResource(R.color.selectedListViewBg);
                }
                else{
                    studentList.getChildAt(i).setBackgroundResource(R.color.listViewBg);
                }   

            }

从数据库中提取学生并将其添加到studentList ArrayAdapter:

getAllStudents(); 

我在

获得了例外
studentList.getChildAt(i).setBackgroundResource(R.color.<either one>);

如果ListView可以保存所有项而不必滚动,则可以选择不使用NullPointerException

我做错了什么?

编辑:

在阅读了这个问题的答案后,我决定改变程序这一部分的逻辑。

我可能应该解释一下我想要做得更好的事情:

我有一个填充了学生的ListView。底部还有一个按钮,上面写着“下一步”。我希望用户能够点击他们的选择并更改背景颜色。这部分代码应该将所选项目的背景更改为一种颜色,将所有其他项目的背景更改为原始颜色。

我的解决方案: 当用户点击ListView项目时,我摆脱了按钮并转到下一页。

2 个答案:

答案 0 :(得分:1)

来自Android开发者参考的引用

public int getCount ()
Since: API Level 1

Returns

    * The number of items owned by the Adapter associated with this AdapterView. (This is the number of data items, which may be larger than the number of visible views.) 

如果ListView包含的项目多于屏幕可以显示的项目,则隐藏列表项目行将保持一个循环,当然,它们将为NULL。当您尝试向上/向下滚动以显示它们时,它们将被充气以显示(调用getView()方法来膨胀这些项目。)

因此,您只能使用屏幕上可见的所有项目行(您可以看到它们)。 解决方案是使用以下两种方法:getFirstVisibleItem()getLastVisibleItem()。除非你知道自己在做什么,否则不要使用getChildAtPosition()

答案 1 :(得分:1)

getChildAt()返回屏幕中指定索引处的ListView子视图。这将仅包含当前呈现的内容(ListView子视图被回收),因此它将始终从0到大约7(例如)。因此,如果您有超过8名学生,那么您正试图在第9位获得一个,这是不存在的。

然而,您的代码(如果它正在工作)的问题在于您无论如何都需要在模型内部存储“选定”状态,否则一旦滚动背景颜色将返回到原始状态。

我建议添加一个复选框小部件并将其设置为选中/取消选中。您仍然需要在模型中保存此信息,并在回收时(在getView()中)相应地设置复选框状态,但在Android环境中比使用背景颜色作为“选定指标”更有意义。

但是要回答原始问题,“修复”代码的最简单方法是使用您正在获取的View参数(v)。

for (int i = 0; i < studentList.getChildCount(); i ++) {
  studentList.getChildAt(i).setBackground(unselected);
}
v.setBackground(selected);

但是再一次,你会注意到滚动后它不会真正起作用。