Custom ArrayAdapter messed up views, with NullPointerException

I am currently developing a content creation app for Android. The main purpose is to give the user the ability to generate a list from text and image records (presented at the end with EditText and ImageView).

I connected this list to ListView by writing a custom ArrayAdapter using the ViewHolder template

@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 the tutorials and examples I've seen, I need to differentiate between layouts that I'm inflating due to the differences between texts and images. And this seems to be causing some problems 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 is being called in the wrong representation, because otherwise there must be an object of type EditText. I'm not really sure when the ListView launches all of its views, and I'm experimenting with my adapter and listing a lot, but I can't figure out why this sometimes clogs up calls to my records. Can anyone help me?

+3


source to share


2 answers


if you don't override getViewTypeCount

, you only get one null convertView

, so you initialize it with image_list_item.xml

or text_list_item.xml

. If you want to handle different types of views, override

 public int getViewTypeCount() {
       return 2;
 }

      

to handle two different types of views, and getItemViewType



public int getItemViewType (int position) {
    Entry e = getItem(position);
    if (e.getType().equals(Entry.Type.IMAGE_ENTRY)) {
        return 0;
    }
    return 1;
}

      

and in getView

check the return valuegetItemViewType

+2


source


The Sample ViewHolder for ListView should be used when you know the item view types before getting started. If they dynamically change when new positions are added (in fact, if notifyDataSetChanged()

called), then there are problems with processing.



For dynamically changing collections with different view types, it is better to use RecyclerView

+1


source







All Articles