在网格视图中使用多选模式

时间:2015-11-27 13:05:00

标签: android image multichoiceitems

我正在创建用于查看图像的应用程序。所以,我决定在网格视图中实现多选择删除图片。我正在使用setMultiChoiceModeListener方法。一切都很好,但我有一个问题...我不能在onDestroyActionMode方法中关闭上下文菜单。我总是得到这样的异常:

 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();
        }
    });

2 个答案:

答案 0 :(得分:0)

class将调用finish(),它不会将您的模式设置为空。

所以你需要的只是:

onDestroyActionMode()

另请注意,如果您想在此处完成动作模式:

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

将其更改为:

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

答案 1 :(得分:0)

我认为您的StackoverflowError是由您执行的&#34; onActionItemClicked()&#34;和&#34; onDestroyActionMode()&#34;:

在&#34; onDestroyActionMode()&#34;中每次执行mode.finish();时,框架将再次调用此方法,因此您创建了一种无限循环。

根据official documentation中的示例,特别是关于在ListView或GridView中启用批处理上下文操作的部分,您应该更改两件事:

1。在执行&#34; onActionItemClicked()&#34;时,请致电

mode.finish();

而不是&#34; onDestroyActionMode()&#34;。

2。在您的&#34; onDestroyActionMode()&#34;中,您不需要致电&#34;完成()&#34;。您可以将此方法覆盖为

  

...在删除CAB时对活动进行必要的更新。默认情况下,取消选中/取消选中所选项目。