自定义 ArrayAdapter 使用 NullPointerException 打乱视图
Custom ArrayAdapter messing up views, with NullPointerException
我目前正在为 Android 开发内容创建应用程序。它的主要目的是让用户从文本和图像条目中生成一个列表(最后由 EditText 和 ImageView 表示)。
我通过在使用 ViewHolder 模式的同时编写自定义 ArrayAdapter 将此列表连接到 ListView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// get current Entry
Entry e = getItem(position);
// variable for holding the view
ViewHolder holder;
// check if there is no view created
if (convertView == null) {
// prepare holder for view to be saved in
holder = new ViewHolder();
// get layout inflater
LayoutInflater inflater = (LayoutInflater) super.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// if current entry is an image entry
if (e.getType().equals(Entry.Type.IMAGE_ENTRY)) {
// inflate layout with ImageView
convertView = inflater.inflate(R.layout.image_list_item,
parent, false);
ImageView iView = (ImageView) convertView
.findViewById(R.id.imageDisplay);
// save inflated view in holder
holder.imageViewItem = iView;
// store the holder with the view
convertView.setTag(holder);
// if it is a text entry
} else if (e.getType().equals(Entry.Type.TEXT_ENTRY)) {
// inflate layout with EditText
convertView = inflater.inflate(R.layout.text_list_item, parent,
false);
EditText tView = (EditText) convertView
.findViewById(R.id.textField);
// save inflated view in holder
holder.editTextItem = tView;
// store the holder with the view
convertView.setTag(holder);
}
} else {
// get holder from existing view
holder = (ViewHolder) convertView.getTag();
}
if (e != null) {
if (e.getType().equals(Entry.Type.IMAGE_ENTRY)) {
// load corresponding image
holder.imageViewItem.setImageBitmap(((ImageEntry) e).getImage());
} else if (e.getType().equals(Entry.Type.TEXT_ENTRY)) {
// load corresponding text
holder.editTextItem.setText(((TextEntry) e).getText());
}
}
return convertView;
}
与我看到的教程和示例相反,由于文本和图像条目之间的差异,我需要区分我膨胀的布局。这似乎造成了一些麻烦,因为有时在一个接一个地添加不同的条目后,我会得到这些异常
E/AndroidRuntime(15812): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
E/AndroidRuntime(15812): at <project>.util.EntryListAdapter.getView(EntryListAdapter.java:104)
所以,在我看来,该方法在错误的视图上被调用,否则必须有一个“EditText”类型的对象。我不太确定 ListView 何时触发其所有视图被重绘,我一直在试验我的适配器并列出很多但我无法弄清楚为什么它有时会弄乱对我的条目的调用。有人可以帮我吗?
当您事先知道位置的视图类型时,应使用 ListView 的 ViewHolder 模式。如果它们要在添加新位置时动态更改(本质上如果正在调用 notifyDataSetChanged()
),那么回收就会出现问题。
对于动态更改具有不同类型视图的集合,最好使用 RecyclerView
如果你不重写getViewTypeCount
,你只会得到一个nullconvertView
,所以你会用image_list_item.xml
或text_list_item.xml
初始化它。如果你想处理不同类型的视图重写
public int getViewTypeCount() {
return 2;
}
处理两种不同类型的视图,getItemViewType
public int getItemViewType (int position) {
Entry e = getItem(position);
if (e.getType().equals(Entry.Type.IMAGE_ENTRY)) {
return 0;
}
return 1;
}
并在 getView
中检查 getItemViewType
的 return 值
我目前正在为 Android 开发内容创建应用程序。它的主要目的是让用户从文本和图像条目中生成一个列表(最后由 EditText 和 ImageView 表示)。
我通过在使用 ViewHolder 模式的同时编写自定义 ArrayAdapter 将此列表连接到 ListView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// get current Entry
Entry e = getItem(position);
// variable for holding the view
ViewHolder holder;
// check if there is no view created
if (convertView == null) {
// prepare holder for view to be saved in
holder = new ViewHolder();
// get layout inflater
LayoutInflater inflater = (LayoutInflater) super.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// if current entry is an image entry
if (e.getType().equals(Entry.Type.IMAGE_ENTRY)) {
// inflate layout with ImageView
convertView = inflater.inflate(R.layout.image_list_item,
parent, false);
ImageView iView = (ImageView) convertView
.findViewById(R.id.imageDisplay);
// save inflated view in holder
holder.imageViewItem = iView;
// store the holder with the view
convertView.setTag(holder);
// if it is a text entry
} else if (e.getType().equals(Entry.Type.TEXT_ENTRY)) {
// inflate layout with EditText
convertView = inflater.inflate(R.layout.text_list_item, parent,
false);
EditText tView = (EditText) convertView
.findViewById(R.id.textField);
// save inflated view in holder
holder.editTextItem = tView;
// store the holder with the view
convertView.setTag(holder);
}
} else {
// get holder from existing view
holder = (ViewHolder) convertView.getTag();
}
if (e != null) {
if (e.getType().equals(Entry.Type.IMAGE_ENTRY)) {
// load corresponding image
holder.imageViewItem.setImageBitmap(((ImageEntry) e).getImage());
} else if (e.getType().equals(Entry.Type.TEXT_ENTRY)) {
// load corresponding text
holder.editTextItem.setText(((TextEntry) e).getText());
}
}
return convertView;
}
与我看到的教程和示例相反,由于文本和图像条目之间的差异,我需要区分我膨胀的布局。这似乎造成了一些麻烦,因为有时在一个接一个地添加不同的条目后,我会得到这些异常
E/AndroidRuntime(15812): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
E/AndroidRuntime(15812): at <project>.util.EntryListAdapter.getView(EntryListAdapter.java:104)
所以,在我看来,该方法在错误的视图上被调用,否则必须有一个“EditText”类型的对象。我不太确定 ListView 何时触发其所有视图被重绘,我一直在试验我的适配器并列出很多但我无法弄清楚为什么它有时会弄乱对我的条目的调用。有人可以帮我吗?
当您事先知道位置的视图类型时,应使用 ListView 的 ViewHolder 模式。如果它们要在添加新位置时动态更改(本质上如果正在调用 notifyDataSetChanged()
),那么回收就会出现问题。
对于动态更改具有不同类型视图的集合,最好使用 RecyclerView
如果你不重写getViewTypeCount
,你只会得到一个nullconvertView
,所以你会用image_list_item.xml
或text_list_item.xml
初始化它。如果你想处理不同类型的视图重写
public int getViewTypeCount() {
return 2;
}
处理两种不同类型的视图,getItemViewType
public int getItemViewType (int position) {
Entry e = getItem(position);
if (e.getType().equals(Entry.Type.IMAGE_ENTRY)) {
return 0;
}
return 1;
}
并在 getView
中检查 getItemViewType