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.xml
ortext_list_item.xml
. If you want to handle differnt types of views overrideto handle two different types of view, and
getItemViewType
and in
getView
check for the return value ofgetItemViewType