Search code examples
androidandroid-cursoradapter

CursorAdapter bindView() does not correctly map to the view returned from newView()


I have a CursorAdapter with newView() and bindView() overridden. The problem is that bindView() does not correctly map to the view created by newView().

newView() returns two different views inflated from different layouts according to a cursor value as below.

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent){
    View view = null;
    int who = //... get a value from cursor

    switch(who){
    case 0:
        view = LayoutInflater.from(context).inflate(R.layout.first, null);
        view.setTag("case 0"); // for bindView() mapping inspection
        break;
    case 1:
        view = LayoutInflater.from(context).inflater(R.layout.second, null);
        view.setTag("case 1"); // for bindView() mapping inspection
        break;
    default:
        break;
    }
    return view;
}

Then, the bindView() is just as usual. Get values from the cursor and set the values to the UI elements in the view returned from newView(). Nothing special. I placed a Log in bindView() showing the view's tag set in newView(). The Log shows that bindView() does not get the desired view when it is called.

I thought that when bindView() is called it binds to the existing view if there is any for memory efficiency. So I figured that bindView gets a specific view possibly identified by row _ID. But it seems that when it is called upon, it just gets ANY existing view.

How can I make bindView gets a designated view with a specific layout when views can have different layouts?


Solution

  • By default, all items in your ListView are considered the same view type. You can override getItemViewType to return a different value based on the position. Then views will be reused only for the same item view type.

    You'll also want to override getViewTypeCount as well as otherwise getItemViewType will not work.