2015-11-27 4 views
0

Я создаю приложение для просмотра изображений. Так, я решил реализовать многопользовательский выбор для изображений в виде сетки. Я использую метод setMultiChoiceModeListener. Все отлично работает, но у меня есть одна проблема. .Я не может закрыть контекстное меню в onDestroyActionMode method.I всегда получают такое исключение:Использование режима множественного выбора в режиме сетки

java.lang.StackOverflowError 
     at android.support.v7.internal.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:174) 
     at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onDestroyActionMode(AppCompatDelegateImplV7.java:1656) 
     at android.support.v7.internal.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:972) 
     at android.support.v7.internal.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:78) 
     at com.example.vasylpaliy.mediaview.ImageList$1.onDestroyActionMode(ImageList.java:91) 
     at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:6604) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3048) 
     at android.support.v7.internal.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:174) 
     at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onDestroyActionMode(AppCompatDelegateImplV7.java:1656) 
     at android.support.v7.internal.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:972) 
     at android.support.v7.internal.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:78) 
     at com.example.vasylpaliy.mediaview.ImageList$1.onDestroyActionMode(ImageList.java:91) 
     at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:6604) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3048) 
     at android.support.v7.internal.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:174) 
     at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onDestroyActionMode(AppCompatDelegateImplV7.java:1656) 
     at android.support.v7.internal.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:972) 
     at android.support.v7.internal.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:78) 
     at com.example.vasylpaliy.mediaview.ImageList$1.onDestroyActionMode(ImageList.java:91) 
     at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:6604) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3048) 
     at android.support.v7.internal.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:174) 
     at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onDestroyActionMode(AppCompatDelegateImplV7.java:1656) 
     at android.support.v7.internal.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:972) 
     at android.support.v7.internal.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:78) 
     at com.example.vasylpaliy.mediaview.ImageList$1.onDestroyActionMode(ImageList.java:91) 
     at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:6604) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3048) 
     at android.support.v7.internal.view.SupportActionModeWrapper$CallbackWrapper.onDestroyActionMode(SupportActionModeWrapper.java:174) 
     at android.support.v7.app.AppCompatDelegateImplV7$ActionModeCallbackWrapperV7.onDestroyActionMode(AppCompatDelegateImplV7.java:1656) 
     at android.support.v7.internal.app.WindowDecorActionBar$ActionModeImpl.finish(WindowDecorActionBar.java:972) 
     at android.support.v7.internal.view.SupportActionModeWrapper.finish(SupportActionModeWrapper.java:78) 
     at com.example.vasylpaliy.mediaview.ImageList$1.onDestroyActionMode(ImageList.java:91) 
     at android.widget.AbsListView$MultiChoiceModeWrapper.onDestroyActionMode(AbsListView.java:6604) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onDestroyActionMode(PhoneWindow.java:3048) 

Вот код:

view.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { 
     private boolean isDeleted; 
     private ArrayList<String> imageItems; 
     { 
      imageItems=new ArrayList<String>(); 
      isDeleted=false; 
     } 
     @Override 
     public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { 
      imageItems.add(imagePaths.get(position)); 
      mode.setTitle("Selected:" + Integer.toString(view.getCheckedItemCount())); 
      imageAdapter.setCheckMark(position); 
      imageAdapter.notifyDataSetChanged(); 
     } 
     @Override 
     public boolean onCreateActionMode(ActionMode mode, Menu menu) { 
      mode.getMenuInflater().inflate(R.menu.multiple_audio, menu); 
      return true; 
     } 
     @Override 
     public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 
      return false; 
     } 

     @Override 
     public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 
      switch (item.getItemId()) 
      { 
       case R.id.multiple_audio_select_all: 
       { 
        imageItems=imagePaths; 
        for(int i=0;i<imageItems.size();i++) 
         view.setItemChecked(i,true); 
        break; 
       } 
       case R.id.multiple_audio_deleting: 
       { 
        deleteItems(imageItems); 
        isDeleted=true; 
        onDestroyActionMode(mode); 
        break; 
       } 
      } 
      return true; 
     } 
     @Override 
     public void onDestroyActionMode(ActionMode mode) { 
      if(mode!=null) 
       mode.finish(); 
     } 
    }); 

ответ

0

Если кому-то нужно создать мульти выбор для RecyclerView, вы посмотрите на this хранилище может. Я считаю это хорошей альтернативой подходу выше.

0

finish() вызовет вызов onDestroyActionMode() он не будет установить режим ноль.

Так все, что вам нужно:

@Override 
public void onDestroyActionMode(ActionMode mode) { 
    // nothing here ;) 
} 

Также отметим, что, если вы хотите, чтобы закончить actionmode здесь:

case R.id.multiple_audio_deleting: 
    { 
    deleteItems(imageItems); 
    isDeleted=true; 
    onDestroyActionMode(mode); 
    break; 
} 

изменить его:

case R.id.multiple_audio_deleting: 
    { 
    deleteItems(imageItems); 
    isDeleted=true; 
    mode.finish(); 
    break; 
} 
0

Я думаю, ваш StackoverflowError вызван вашей реализацией «onActionItemClicked()» и «onDestroyActionMode()»:

С каждым выполнением mode.finish(); в «onDestroyActionMode()» инфраструктура будет вызывать именно этот метод еще раз, поэтому вы создаете своего рода бесконечный цикл.

По выборке из official documentation, особенно часть о Включение пакетных контекстных действий в ListView или GridView, вы должны изменить две вещи:

1. В вашей реализации «onActionItemClicked() ", позвонить по телефону

mode.finish(); 

вместо" onDestroyActionMode() ".

2. В вашем «onDestroyActionMode()» вам не нужно называть «finish()». Вы можете переопределить этот метод до

... внести необходимые обновления в действие при удалении CAB. По умолчанию выбранные элементы отменены или не отмечены.

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