当我在ListView中滚动后点击一行时,为什么我得到CheckedTextView的NullPointerException?

时间:2013-09-30 13:56:30

标签: android listview android-listview onitemclicklistener

我的活动中有一个ListView。以下是我在ListView

的行上设置OnCLickListener的方式
 listview.setAdapter(new RowsArrayAdapter(this, rows));

 listview.setOnItemClickListener(new OnItemClickListener() {
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         CheckedTextView ctv = (CheckedTextView) lv.getChildAt(position).findViewById(R.id.row_checkbox);
         ctv.setChecked(true);

 });
RowsArrayAdapter的

getView()方法如下:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

         LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

         View rowView = inflater.inflate(R.layout.row_layout, parent, false);

         CheckedTextView row = (CheckedTextView) rowView.findViewById(R.id.row_checkbox);
         row.setText(values[position].getRow_no());

         return rowView;
}

它适用于前8行。我检查了数组行的长度。它的16是对的。但是当我向下滚动并单击某行(例如第12行)时,它会给我NullPointerException。知道为什么会这样,我该如何解决它。提前谢谢。

3 个答案:

答案 0 :(得分:2)

这会产生null:

CheckedTextView ctv = (CheckedTextView) lv.getChildAt(position).findViewById(R.id.row_checkbox);
ctv.setChecked(true);

但这不是:

CheckedTextView ctv = (CheckedTextView)  lv.getAdapter().getView(position, null,  lv).findViewById(R.id.row_checkbox);
ctv.setChecked(true);

请试试这个

答案 1 :(得分:0)

你应该使用。

 CheckedTextView ctv = (CheckedTextView) view.findViewById(R.id.row_checkbox);

答案 2 :(得分:0)

您不应将状态存储在行视图中。即使您能够找到正确的行并将复选框设置为选中状态,当您向后滚动时也会出现问题。为了解决这个问题,我建议你在模型中添加checked flag并在你的适配器的getView方法中填充checked状态。在onClick侦听器中,您需要在适配器上修改模型和notifyDataSetChanged。

每次在getView方法中都不应该为同一个视图充气,否则会产生非常糟糕的性能。只有当convertView == null时才应对它进行充气,否则只需重用转换视图。

我强烈建议您使用RecyclerView而不是listview,因为它强制使用ViewHolder模式。在此处阅读更多内容:https://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder