Reputation: 15492
I have a list of items.
I want to delete an item in a long push.
I saw this post and it worked for me.
just out of curiosity i wonder why other solution didn't work for me:
sol 1
I register the list to context menu:
registerForContextMenu(listView);
and then:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
if (v.getId()==R.id.comments_list) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.phone_list_contextual_menu, menu);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()) {
case R.id.edit: {
return true;
}
case R.id.delete: {
comments.remove(info.id);
listView.invalidate();
return true;
}
default: {
return super.onContextItemSelected(item);
}
}
}
Is there a difference between
listView.invalidate()
and adapter.notifyDataHasChanged()
? beside the subject of the call?
what am I missing in order for the remove to work?
sol 2
listView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int position = (int) v.getTag();
comments.remove(position);
listView.invalidate();
return true;
}
});
instead of
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
comments.remove(pos);
//listView.invalidate();
arrayAdapter.notifyDataSetChanged();
return true;
}
});
I understand setOnItemLongClickListener
is more suitable for my need than setOnLongClickListener
but yet
why didn't this worked for me?
Upvotes: 3
Views: 1126
Reputation: 50026
Is there a difference between
listView.invalidate() and adapter.notifyDataHasChanged() ? beside the subject of the call?
To my understanding adapter.notifyDataHasChanged() will do what listView.invalidate() plus more. That means it will also include change in number of items, and possibly inform other observers of data change. Relevant code is here:
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AdapterView.java#798
this is for notifyDataHasChanged(), as you can see mItemCount is udpated with new value. This means if you add more items to your arrayadapter, then invalidate, or better invalidateViews will not show them, at least at the end of list. One thing I have noticed is that above code has no invalidate call - maybe its called by some other methods.
Below is source code for invalidateViews (which is I think more proper than Invalidate):
http://androidxref.com/5.0.0_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#5078
It has no code to update count of item.
If you search source code for android sources, you will find only few cases when invalidateViews is called, some of those places are optimization hacks.
Upvotes: 1
Reputation: 1015
The difference is that invalidate
causes all your views in the list to be scrapped and redrawn. Note I said views so that is what you are actually seeing on the screen (for example you can have 3 views on screen but 20 items in your list)
notifyDataHasChanged
on the other hand tells the adapter that the contents have changed and the adapter needs to re-run its methods on the content to refresh the list.
You almost always want to use notifyDataHasChanged
but it depends on exactly what you are trying to accomplish.
Hope that helps.
Upvotes: 1