2012-04-20 2 views
8

У меня есть ListView, который обычно является singleChoicechoiceMode. Когда пользователь долго нажимает на элемент, я хочу ввести режим действия, который позволяет выбирать несколько элементов, чтобы они могли выполнять действие над любыми выбранными элементами.Изменить ListView selectionMode from singleChoice to multipleChoiceModal

Я могу настроить ListView так, чтобы он находился в режиме singleChoice, и пользователь может выбрать элементы списка, чтобы отобразить фрагмент деталей рядом с ним, и сам элемент списка показан в его активированном состоянии.

Я также возможность настроить ListView так, что он находится в multipleChoiceModalchoiceMode и выполняя длительное нажатие на элементе начинается режим действия и позволяет множественный выбор, но теперь ListView не допустит ни одного выбора в нормальном (без режима действия).

Как я могу использовать ListView, который находится в режиме singleChoice, а затем перевести его в режим multipleChoiceModal, когда элемент длинным нажатием?

Это ближайший я смог придумать:

  1. установить ListView в режим singleChoice
  2. установить ListView-х OnItemLongClickListener и в этом слушателю:
    1. установить ListView-х OnItemLongClickListener до null
    2. установить ListView's choiceMode на multipleChoiceModal
    3. звоните view.performClick() по вопросу, который был долго нажат.

Этот подход имеет несколько проблем.

  1. Режим действия не запускается до второго раза, когда я долго нажимаю на элемент.
  2. Когда я звоню getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); в onDestroyActionMode, я получаю java.lang.StackOverflowError, потому что этот метод также пытается уничтожить также режим действия (но мы еще не вернулись из уничтожения).
+0

что должно произойти после того, как вы вводите multipleChoiceMode, выбранный 2 и вернуться к singleCheckMode? – user387184

ответ

3

Я использовал это в одной из моих программ

с нами ListView.CHOICE_MODE_MULTIPLE_MODAL затем 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); 
     } 
    } 

} 

это позволяет для одного выбора одного клика и списка следует множественному выбор длинного клика. Это все вытащили из приложения для обмена сообщениями ICS, чтобы вы могли просматривать это слишком.

+0

Возможно, мне что-то не хватает, но как этот список переходит в singleChoiceMode после того, как режим действия уничтожен? –

+0

просто переопределите 'onListItemClick' в списке, а затем, когда пользователь нажимает элемент в списке, отображает фрагмент, относящийся к клику. если я здесь что-то не хватает? – tyczj

+0

Я предполагаю, что часть, о которой я не упоминал, состоит в том, что мои элементы списка используют state_activated. state_activated только присваивается значение true, когда элемент действительно выбран в качестве выбора в режиме singleChoice, поэтому я действительно хочу, чтобы мой ListView возвращался в режим singleChoice. –

5

Это действительно показалось, что это переключатель режима выбора, поскольку нет чистого и простого решения, которое я мог бы сделать Google. HFM (есть вера человека) и ПОЦЕЛУЙ (держать его просто глупо) помог;)

1.Start в выборе одного режима и установить все слушатели (это делается, где вы установите адаптер список)

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

2.реализовать интерфейсы для переключения между режимами выбора. TRICK, чтобы заставить его работать, - это вернуться в режим одиночного выбора вне реализации, то есть ПОСЛЕ того, как вы уничтожите режим действия! Поэтому просто используйте простой флаг, чтобы отметить уничтожение CAB. Другой TRICK должен вернуть false onItemLongClick, чтобы режим выбора успел вступить в силу.

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 является переключатель назад

@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); 

    } 
+0

Извините, что вернул старый пост, но я пробовал описанный выше способ, но мои элементы listView не выделены синим цветом (например, на whatsapp). Как я могу это сделать? Благодаря ! – Leonardo

+0

Если пользовательский интерфейс требует перехода и обратно обратно через рекреацию (например, когда пользовательский интерфейс основан на фрагменте), не забудьте переключить состояние ListView на «ListView.CHOICE_MODE_SINGLE», если он был в «ListView.CHOICE_MODE_MULTIPLE_MODAL» в момент увольнения. Кроме того, держите переключения переключения переключения между MULTI и SINGLE. Я делаю это вот так: if (! IsCABDestroyed) { \t int selection = contentList.getCheckedItemPositions(). KeyAt (0); \t contentList.setChoiceMode (ListView.CHOICE_MODE_SINGLE); \t contentList.setItemChecked (выбор, истина); } // удаляем навигацию – StAlex

 Смежные вопросы

  • Нет связанных вопросов^_^