Change ListView choiceMode from singleChoice to multipleChoiceModal

亡梦爱人 提交于 2019-11-30 12:43:26

I used this in one of my programs

us the ListView.CHOICE_MODE_MULTIPLE_MODAL then lv.setMultiChoiceModeListener(new ModeCallBack());

    public class ModeCallBack implements ListView.MultiChoiceModeListener{

    View mSelectView;
    TextView mSelectedCount;
    ArrayList<Long> mCheckedItems;

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
        SharedPreferences.Editor edit = pref.edit();

        if(item.getItemId() == R.id.bowler_delete){

            for(int i=0; i<mCheckedItems.size(); i++){
                long id = mCheckedItems.get(i);

                getActivity().getContentResolver().delete(BowlersDB.CONTENT_URI,BowlersDB.ID+"="+id,null);
            }
        }else if(item.getItemId() == R.id.bowler_add_ball){
            if(mCheckedItems.size() > 1){
                Toast.makeText(getActivity(),"Can only add bowling balls to one bowler at a time",Toast.LENGTH_SHORT).show();
            }else{
                edit.putLong(Preferences.BOWLER_SELECTED_FOR_BALL,mCheckedItems.get(0)).commit();

                ListFragment lf = new ManufacturersList();
                FragmentTransaction ft;
                ft = getFragmentManager().beginTransaction();
                ft.replace(R.id.frameOne, lf).addToBackStack(null).commit();
                //mRemover.rFragment();
            }
        }else if(item.getItemId() == R.id.add_bowler_to_team){
            for(int i=0; i<mCheckedItems.size(); i++){

                long id = mCheckedItems.get(i);
                ContentValues values = new ContentValues();
                values.put(TeamBowlers.BOWLER_ID,id);
                values.put(TeamBowlers.TEAM_ID,pref.getLong(Preferences.TEAM_SELECTED,1));
                getActivity().getContentResolver().insert(TeamBowlers.CONTENT_URI, values);

            }
            FragmentManager fm = getFragmentManager();
            fm.popBackStack();
        }
        mode.finish();
        return true;
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflate = getActivity().getMenuInflater();
        if(fromTeam){
            inflate.inflate(R.menu.bowlers_team_action_menu, menu);
        }else{
            inflate.inflate(R.menu.bowler_action_menu, menu);
        }
        if(mSelectView == null){
            mSelectView = (ViewGroup)LayoutInflater.from(getActivity()).inflate(R.layout.select_count_layout,null);

            mSelectedCount = (TextView)mSelectView.findViewById(R.id.count_tv);

        }
        if(mCheckedItems == null){
            mCheckedItems = new ArrayList<Long>();
        }
        mode.setCustomView(mSelectView);
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mCheckedItems = null;

    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        if(mSelectView == null){
            mSelectView = (ViewGroup)LayoutInflater.from(getActivity()).inflate(R.layout.select_count_layout,null);

            mSelectedCount = (TextView)mSelectView.findViewById(R.id.count_tv);
        }

        if(mCheckedItems == null){
            mCheckedItems = new ArrayList<Long>();
        }
        return true;
    }

    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position,long id, boolean checked) {         

        final int count = lv.getCheckedItemCount();
        mSelectedCount.setText(String.valueOf(count));
        if(checked){
            mCheckedItems.add(id);
        }else{
            mCheckedItems.remove(id);
        }
    }

}

this allows for single choice single listview click and long click multiple selection. This was all pulled from the ICS messaging app so you can browse that too

Gabriel Costea

It really seemed awkard this choice mode switch since there is no clean and simple solution I could google. HFM (have faith man) and KISS (keep it simple stupid) helped ;)

1.start in single mode choice and set all the listeners (this is done where you set the list adapter)

listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 
listView.setOnItemLongClickListener(liListener);
listView.setMultiChoiceModeListener(mcListener);

2.implement the interfaces to switch between choice modes. The TRICK to make it work is to switch back to single choice mode outside the implementation, meaning AFTER you destroy the action mode!! So just use a simple flag to mark the CAB destruction. Another TRICK is to return false onItemLongClick so that the the choice mode have time to get into effect.

private OnItemLongClickListener liListener = new OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                int position, long id) {                
            listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
            isCABDestroyed = false;                 
            return false; // so this action does not consume the event!!!
        }
    };

private MultiChoiceModeListener mcListener = new MultiChoiceModeListener() {
    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position,
                                          long id, boolean checked) {
        final int checkedCount = listView.getCheckedItemCount();
        switch (checkedCount) {
            case 0:
                mode.setSubtitle(null);
                break;
            case 1:
                mode.setSubtitle("One item selected");
                break;
            default:
                mode.setSubtitle("" + checkedCount + " items selected");
                break;
        }
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
            case R.id.delete:
                //do your action command here
                mode.finish();
                return true;
            default:
                return false;
        }
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        isCABDestroyed = true; // mark readiness to switch back to SINGLE CHOICE after the CABis destroyed  

    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }
};

3.Here is the switch back

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);  
        if(isCABDestroyed) {
            listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            //do your action command  here
        }
        l.setItemChecked(position, true);

    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!