在BaseAdapter的View中使用viewHolder时获取空对象引用

时间:2018-12-25 23:06:12

标签: android baseadapter android-viewholder null-object-pattern

我在BaseAdapter中有一个视图,该视图正常工作。在这里:

public class lv_cb_db_ea_Adapter extends BaseAdapter {

final private Context context;
private Cursor cursor;

lv_cb_db_ea_Adapter(Context context, Cursor cursor) {
    super();
    this.context = context;
    this.cursor = cursor;
}

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

    LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = layoutInflater.inflate(R.layout.list_item, parent, false);

    TextView tvTextView = view.findViewById(R.id.listItem_TextView);
    CheckBox cbCheckBox = view.findViewById(R.id.listItem_CheckBox);

    cursor.moveToPosition(position);

    // create string for TextView
    String sTextView =
            cursor.getString(cursor.getColumnIndex("name")) +
                    " (" + cursor.getString(cursor.getColumnIndex("code")) + ")";

    tvTextView.setText(sTextView);
    cbCheckBox.setChecked(cursor.getInt(cursor.getColumnIndex("selected")) != 0);

    return view;
}

public int getCount() {
    return cursor.getCount();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

}

我只有一个警告:使用ViewHolder,所以我做到了:

public class lv_cb_db_ea_Adapter extends BaseAdapter {

final private Context context;
private Cursor cursor;

lv_cb_db_ea_Adapter(Context context, Cursor cursor) {
    super();
    this.context = context;
    this.cursor = cursor;
}

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

    ViewHolder viewHolder;

    if (convertView == null) {

        LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = layoutInflater.inflate(R.layout.list_item, parent, false);

        viewHolder = (ViewHolder) convertView.getTag();

        viewHolder.list_item_TextView = convertView.findViewById(R.id.listItem_TextView);
        viewHolder.list_item_Checkbox = convertView.findViewById(R.id.listItem_CheckBox);

    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    cursor.moveToPosition(position);

    // create string for TextView
    String sTextView =
            cursor.getString(cursor.getColumnIndex("name")) +
                    " (" + cursor.getString(cursor.getColumnIndex("code")) + ")";

    viewHolder.list_item_TextView.setText(sTextView);
    viewHolder.list_item_Checkbox.setChecked(cursor.getInt(cursor.getColumnIndex("selected")) != 0);

    return convertView;
}

public int getCount() {
    return cursor.getCount();
}

public Object getItem(int position) {
    return position;
}

public long getItemId(int position) {
    return position;
}

private static class ViewHolder {
    // fields from list_item.xml
    CheckBox list_item_Checkbox;
    TextView list_item_TextView;
}

}

但是当我使用ViewHolder运行类时,它将引发致命异常: 这是我的logcat的一部分:

2018-12-25 23:44:19.379 18010-18033/? D/EGL_emulation: eglMakeCurrent: 0xde285180: ver 3 0 (tinfo 0xde283690)
2018-12-25 23:44:19.547 18010-18010/? D/AndroidRuntime: Shutting down VM
2018-12-25 23:44:19.588 18010-18010/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: ws.rtin.android.listviewexample, PID: 18010
java.lang.NullPointerException: Attempt to write to field 'android.widget.TextView ws.rtin.android.listviewexample.lv_cb_db_ea_Adapter$ViewHolder.list_item_Text    View' on a null object reference
    at ws.rtin.android.listviewexample.lv_cb_db_ea_Adapter.getView(lv_cb_db_ea_Adapter.java:35)
    at android.widget.AbsListView.obtainView(AbsListView.java:2366)
    at android.widget.ListView.makeAndAddView(ListView.java:2052)
    at android.widget.ListView.fillDown(ListView.java:786)
    at android.widget.ListView.fillFromTop(ListView.java:847)

我有一个类似的应用程序,它使用ArrayAdapter和ListView,一切正常。我找不到错误。 错误指向该行:

viewHolder.list_item_TextView = convertView.findViewById(R.id.listItem_TextView);

我也尝试过:

view = layoutInflater.inflate(R.layout.list_item, null);

代替

view = layoutInflater.inflate(R.layout.list_item, parent, false);

没有成功。

我做到了:

System.out.println(convertView.findViewById(R.id.listItem_TextView));

  

android.widget.TextView {5e43116 V.ED ..... ...... ID 0,0-0,0#7f070047 app:id / listItem_TextView}

System.out.println(viewHolder.list_item_TextView);

  

java.lang.NullPointerException:尝试从空对象引用上的字段“ android.widget.TextView ws.rtin.android.listviewexample.lv_cb_db_ea_Adapter $ ViewHolder.list_item_TextView”中读取

所以我认为,这一定是ViewHolder的问题,而不是TextView的问题。 当然,viewHolder必须为null,因为它是在条件“ if(convertView == null){”中定义的,但是在所有示例中,我都认为这是可行的。

0 个答案:

没有答案