问题
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 byadapter.notifyDataSetChanged()
after the data was updated. - called
adapter.changeCursor(newCursor)
followed byadapter.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;
}
来源:https://stackoverflow.com/questions/17004240/changing-cursor-in-cursoradapter-is-not-properly-updating-list-item-views