I am currently developing a content-creation application for Android. It´s main purpose is to let the user generate a list out of text and image entries (represented in the end by EditText and ImageView).
I hooked this list up to a ListView by writing a custom ArrayAdapter whilst using the ViewHolder Pattern
@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;
}
Contrary to tutorials and examples I´ve seen I need to distinguish between the layouts I inflate due to the difference between text and image entries. And this seems to be causing some trouble because sometimes after adding different entries after another I get these exceptions
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)
So, it seems to me that the method gets called on the wrong view because otherwise there has to be an object of the type ‘EditText’. I´m not quite certain when the ListView triggers all its views to be redrawn and I´ve been experimenting with my adapter and list a lot but I can´t work out why it sometimes messes up the calls for my entries. Can anyone help me there?
if you don't override
getViewTypeCount, you will get only one nullconvertView, so you will initialize it withimage_list_item.xmlortext_list_item.xml. If you want to handle differnt types of views overrideto handle two different types of view, and
getItemViewTypeand in
getViewcheck for the return value ofgetItemViewType