Is there a difference between `listView.invalidate ()` and `adapter.notifyDataHasChanged ()`?

I have a list of items.

I want to delete an item with a long press.

I saw this post and it worked for me.

Just out of curiosity, I am wondering why the other solution did not work for me:

sol 1

I register the list in the 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 any difference between

listView.invalidate()

and adapter.notifyDataHasChanged()

? besides the subject of the challenge?

what am I missing to delete a job?

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

  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 that setOnItemLongClickListener

more suits my need than setOnLongClickListener

, but still

why didn't it work for me?

+3


source to share


2 answers


Is there any difference between

listView.invalidate () and adapter.notifyDataHasChanged ()? besides the subject of the challenge?

In my understanding, adapter.notifyDataHasChanged () will do what listView.invalidate () plus more. This means that it will also include a change in the number of items and possibly inform other observers about the change in data. The 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 the mItemCount collapses with a new value. This means that if you add more items to your array, then invalidateViews will not show them, at least at the end of the list. One thing I noticed is that there is no invalid call above the code - it may have been called by other methods.



Below is the source code for invalidateViews (which I think is more correct 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 the cardinality.

If you are looking for source code for android sources, you will only find a few cases where invalidateViews is called, some of these places are optimization hacks.

+1


source


The difference is what invalidate

causes all your views on the list to be canceled and redrawn. Note that I said opinions, so what you actually see on the screen (for example, you can have 3 views on the screen, but 20 items in your list)

notifyDataHasChanged

, on the other hand, informs the adapter that the content has changed and the adapter needs to rerun its methods on the content to update the list.



You almost always want to use notifyDataHasChanged

, but it depends on what you are trying to accomplish.

Hope it helps.

+1


source







All Articles