Changing cursor in CursorAdapter is not properly u

2019-07-20 08:33发布

问题:

This question is very similar to many other questions on StackOverflow, but I think it merits its own post due to a difference in approach compared to other questions here.

I have a custom adapter that extends CursorAdapter. I'm updating the data and calling notifyChange on the appropriate URI in order to refresh the cursor. In debugging, I can see that this is working properly.

Unfortunately, my list views are not being recreated. The reason that I need them to be recreated is because of my newView implementation on the adapter:

public View newView(final Context context, final Ingredient ingredient, final ViewGroup parent) {
    final int layout = ingredient.isOwned() ? LAYOUT_OWNED : LAYOUT_UNOWNED;
    final View view = LayoutInflater.from(context).inflate(layout, null);

    // ... ViewHolder magic

    return view;
}

The problem is that calling notifyChange is updating the list data, but it is not recreating the view that I need via newView.

Here are some other things I tried that equally did not work:

  • called adapter.notifyDataSetChanged() after the data was updated.
  • called contentResolver.notifyChange(...) followed by adapter.notifyDataSetChanged() after the data was updated.
  • called adapter.changeCursor(newCursor) followed by adapter.notifyDataSetChanged().
  • called view.invalidate() on the specific list item that changed.

Any other suggestions on how to approach this?

Edit: I may altogether just be taking the wrong approach. I misunderstood the recycling of views within adapters, and I see that the wrong type of view is being used when recycled. As such, I'll probably need to go about styling my views using another approach. The reason I was taking this approach in the first place is due to my desire to use styles, which can't be set programmatically other than inflating a view as explained in this StackOverflow question. I'm open to approaches that will take advantage of that answer while properly recycling list item views.

回答1:

I ended up figuring out the problem based upon this StackOverflow answer. I needed to override getItemTypeCount and getItemViewType on my adapter.

@Override
public int getItemViewType(int position) {
    return getItem(position).isOwned() ? 1 : 0;
}

@Override
public int getViewTypeCount() {
    return 2;
}