维护方向更改时的项目选择

时间:2014-06-18 20:58:56

标签: android android-fragments android-support-library

我正在尝试恢复方向更改的操作模式的状态。但它不能正常工作。按照以下步骤顺序,在#3和#4中,选择被破坏:

  1. 长按项目 - 项目突出显示,上下文操作栏显示,标题显示“1选中”。看起来不错。
  2. 将手机转为横向 - 无变化。看起来不错。
  3. 将手机重新设为纵向 - 项目未突出显示,上下文操作栏已消失
  4. 长按项目 - 项目突出显示,上下文操作栏显示标题显示“0已选择”
  5. myListView.getCheckedItemCount()中的

    onSaveInstanceState()在#3上返回0。这就是问题开始的地方。

    我的片段(使用支持库)我做错了什么?

    @Override
    public void onSaveInstanceState(Bundle outState) {
        //check if any items are selected
        if (myListView.getCheckedItemCount() > 0) {
            //get the list of selected items and convert it to an int Array
            //because SparseBooleanArray cannot be stored in a bundle
            SparseBooleanArray selectedItems = myListView.getCheckedItemPositions();
            int[] selectedItems_intArray = new int[myListView.getCheckedItemCount()];
            for (int i = 0; i < selectedItems.size(); i++) {
                if (selectedItems.valueAt(i) == false)
                    continue;
                selectedItems_intArray[i] = selectedItems.keyAt(i);
            }
            outState.putIntArray(KEY_CHECKED_ITEMS, selectedItems_intArray);
        }
    }
    
    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        if (savedInstanceState != null) {
            int[] checkedItems = savedInstanceState.getIntArray(KEY_CHECKED_ITEMS);
            if (checkedItems != null) {
                actionMode = ((ActionBarActivity) getActivity()).startSupportActionMode(new ContextualActionBarActionModeCallBack());
    
                for (int i = 0; i < checkedItems.length; i++) {
                    myListView.setItemChecked(checkedItems[i], true);
                }
    
                actionMode.setTitle(myListView.getCheckedItemCount() + " selected");
            }
        }
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        myListView = (ListView) getActivity().findViewById(R.id.myListView);
        adpt = new myCustomCursorAdapter(getActivity());
        myListView.setAdapter(adpt);
        //Choice mode is allowed only after a long click
        //disabling it on first time load
        myListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
            myListView.setOnItemLongClickListener(new OnItemLongClickListener(){
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id){
                if(actionMode == null){
                    //Start the action mode
                    actionMode = ((ActionBarActivity)getActivity()).startSupportActionMode(new ContextualActionBarActionModeCallBack());
    
                    myLisVIew.setItemChecked(position, true);                           
                    actionMode.setTitle(myListView.getCheckedItemCount() + " selected");
                    return true;
                    }
                else return false;
            }
        });
    }
    
    @Override
    public void onResume(){
        super.onResume();
        getLoaderManager().initLoader(0,null,this);
    }
    
    private class ContextualActionBarActionModeCallBack implements ActionMode.Callback{
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.mycontextmenu, menu);   
            myListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        }
        ...
        ...
    }
    

    ListView布局元素:

    <ListView
            android:id="@+id/myListView"
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:layout_alignParentTop="true"
            android:listSelector="@android:color/transparent"
            android:stackFromBottom="true"
            android:layout_above="@id/layout_input"
            android:divider="#00000000"
            />
    

1 个答案:

答案 0 :(得分:7)

问题在于,每次在方向更改时创建列表视图时,列表视图的选择模式都会重置为默认值CHOICE_MODE_NONE,因为列表视图布局中未明确定义选择模式文件。发生这种情况的Android来源 - http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#815

解决方案是添加:

android:choiceMode="multipleChoice"

到列表视图布局。

这也意味着无需在onSaveInstanceState()中手动存储列表视图选择,并在onViewStateRestored()中检索它。它由片段自动完成。所以删除这两个功能。只需在onResume中启动操作模式:

@Override
    public void onResume() {
        super.onResume();
            getLoaderManager().initLoader(0,null,this);
            if (myListView.getCheckedItemCount() > 0 && actionMode == null) {
            actionMode = ((ActionBarActivity) getActivity()).startSupportActionMode(new ContextualActionBarActionModeCallBack());
            actionMode.setTitle(myListView.getCheckedItemCount() + " selected");
        }
    }

注意:如果您已实现LoaderManager.LoaderCallBacks接口并且需要在方向更改后访问适配器项,请在适配器加载后在onLoadFinished()中执行此操作与数据源。在onResume()中执行此操作会导致NPE