scottysseus
scottysseus

Reputation: 2010

Refresh ListView from ActionMode.Callback.onDestroyActionMode()

This is a question that has been floating around on StackOverflow for a little while, and before you mark this question as a duplicate I am aware of this link. However, this question is vague, has no code, and doesn't seem to have been fully answered.

So on to my question:

I have a ListFragment (MainListFragment) that, onLongItemClick, opens up a Contextual Action Bar. One of the menu items within this Contextual Action Bar enables the deletion of the ListView item that was long-clicked.

Within the class that implements ActionMode.Callback, I am able to delete the long-clicked item, but I need the ListView to refresh itself after this deletion so users don't have to switch Fragments to see the effects of the deletion.

Here you can see my onLongItemClickListener within MainListFragment:

this.getListView().setOnItemLongClickListener(new OnItemLongClickListener(){

        @Override
        public boolean onItemLongClick(AdapterView<?> adapter, View view,
                int pos, long id) {
            // TODO Auto-generated method stub
            Log.d("My Debug Bitches", "made it to the listener");
            MainListContextualMenu menu = new MainListContextualMenu();
            //view.startActionMode(menu);
            ActionMode mode = getActivity().startActionMode(menu);
            Object[] tags = new Object[2];
            tags[0] = view.getRootView().getContext();
            tags[1] = pos;
            mode.setTag(tags);
            //view.setSelected(true);
            return true;
        }

    });

And here is my ActionMode.Callback-implementing class:

public class MainListContextualMenu implements ActionMode.Callback{

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    // TODO Auto-generated method stub

    switch(item.getItemId()){
    case R.id.main_list_contextual_menu_delete:

        //MainActivity activity = (MainActivity) mode.getCustomView().getContext();
        //activity.getLists().remove(mode.getTag());

        Object[] tags = (Object[]) mode.getTag();
        MainActivity activity = (MainActivity) tags[0];
        int index = (Integer) tags[1];
        //Log.d("My Debug Bitches","" +index);
        //Log.d("My Debug Bitches", "size before " + activity.getLists().size());
        activity.getLists().remove(index);
        //Log.d("My Debug Bitches", "size after " + activity.getLists().size());
        break;
    case R.id.main_list_contextual_menu_edit:
        break;
    }


    return false;
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    // TODO Auto-generated method stub
    MenuInflater inflater = mode.getMenuInflater();
    inflater.inflate(R.menu.main_list_contextual_menu, menu);
    Log.d("My Debug Bitches", "menu inflated");
    return true;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
    // TODO Auto-generated method stub
    Object[] tags = (Object[]) mode.getTag();
    MainActivity activity = (MainActivity) tags[0];
    ListView view = (ListView) activity.getCurrentFocus();
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    // TODO Auto-generated method stub
    return false;
}

}

I have tried using invalidateViews() within my onDestroyActionMode() method to no avail, and I have seen others recommend notifyDataSetChange().

However, I am not sure how to use these solutions within an ActionMode.Callback. If you look at my onLongClick() method, I use mode.setTag() to pass both the MainActivity and the position of the ListView item that was clicked. Is this good form?

I just want to be able to refresh the ListView from MainListFragment within the ActionMode.Callback.onDestroyActionMode() method.

Has anyone gotten this to work before, and if so, does he/she have any suggestions?

Upvotes: 0

Views: 1260

Answers (1)

keshav
keshav

Reputation: 3255

I am suggesting this answer according to your implementation,there may be a better way, first create a method getAdapter() which will return your adapter which you are using for your listview.

ArrayAdapter adapter;

public ArrayAdapter getAdapter()
    {
        // TODO Auto-generated method stub
        return adapter;
    }

Now change your code like this this, add this activity.getAdapter().notifyDataSetChanged();

case R.id.main_list_contextual_menu_delete:

        //MainActivity activity = (MainActivity) mode.getCustomView().getContext();
        //activity.getLists().remove(mode.getTag());

        Object[] tags = (Object[]) mode.getTag();
        MainActivity activity = (MainActivity) tags[0];
        int index = (Integer) tags[1];
        //Log.d("My Debug Bitches","" +index);
        //Log.d("My Debug Bitches", "size before " + activity.getLists().size());
        activity.getLists().remove(index);
        activity.getAdapter().notifyDataSetChanged();
        //Log.d("My Debug Bitches", "size after " + activity.getLists().size());
        break;

Hope it will help.

Upvotes: 1

Related Questions