维持方向变化项目选择 [英] maintain Item selection on orientation change

查看:126
本文介绍了维持方向变化项目选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图恢复对方向变化的行动模式的状态。但它不能正常工作。在按照以下顺序的步骤,#3,#4的选择出现了问题:

  1. 长按一个项目 - 项目高亮显示,上下文操作栏显示了标题显示1选择。看起来很不错。
  2. 打开手机的风景 - 没有变化。看起来很不错。
  3. 打开手机回肖像 - 项目不突出,上下文操作栏不见了
  4. 长按一个项目 - 项目高亮显示,上下文操作栏显示了标题显示0选择

myListView.getCheckedItemCount()的onSaveInstanceState()在3号返回0。这就是问题的开始。

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

  @覆盖
公共无效的onSaveInstanceState(包outState){
    //检查是否有物品被选中
    如果(myListView.getCheckedItemCount()大于0){
        //获取选定项的列表,并将其转换为int数组
        //因为SparseBooleanArray不能存储在一个包
        SparseBooleanArray selectedItems = myListView.getCheckedItemPositions();
        INT [] selectedItems_intArray =新INT [myListView.getCheckedItemCount()];
        的for(int i = 0; I< selectedItems.size();我++){
            如果(selectedItems.valueAt(一)==假)
                继续;
            selectedItems_intArray [I] = selectedItems.keyAt(ⅰ);
        }
        outState.putIntArray(KEY_CHECKED_ITEMS,selectedItems_intArray);
    }
}

@覆盖
公共无效onViewStateRestored(包savedInstanceState){
    super.onViewStateRestored(savedInstanceState);
    如果(savedInstanceState!= NULL){
        INT [] checkedItems = savedInstanceState.getIntArray(KEY_CHECKED_ITEMS);
        如果(checkedItems!= NULL){
            actionMode =((ActionBarActivity)getActivity())startSupportActionMode(新ContextualActionBarActionModeCallBack())。

            的for(int i = 0; I< checkedItems.length;我++){
                myListView.setItemChecked(checkedItems [I]中,真);
            }

            actionMode.setTitle(myListView.getCheckedItemCount()+选择);
        }
    }
}

@覆盖
公共无效onActivityCreated(包savedInstanceState){
    super.onActivityCreated(savedInstanceState);
    。myListView =(ListView控件)getActivity()findViewById(R.id.myListView);
    ADPT =新myCustomCursorAdapter(getActivity());
    myListView.setAdapter(ADPT);
    //选择模式后,长按只允许
    //禁用它在第一次加载
    myListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
        myListView.setOnItemLongClickListener(新OnItemLongClickListener(){
        @覆盖
        公共布尔onItemLongClick(适配器视图<>母公司视图中查看,INT位置,长的id){
            如果(actionMode == NULL){
                //开始的动作模式
                actionMode =((ActionBarActivity)getActivity())startSupportActionMode(新ContextualActionBarActionModeCallBack())。

                myLisVIew.setItemChecked(位置,真正的);
                actionMode.setTitle(myListView.getCheckedItemCount()+选择);
                返回true;
                }
            否则返回false;
        }
    });
}

@覆盖
公共无效onResume(){
    super.onResume();
    getLoaderManager()initLoader(0,空,这一点)。
}

私有类ContextualActionBarActionModeCallBack实现ActionMode.Callback {
    @覆盖
    公共布尔onCreateActionMode(ActionMode模式,菜单菜单){
        MenuInflater充气= mode.getMenuInflater();
        inflater.inflate(R.menu.mycontextmenu,菜单);
        myListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    }
    ...
    ...
}
 

的ListView布局元素:

 <的ListView
        机器人:ID =@ + ID / myListView
        机器人:layout_height =match_parent
        机器人:layout_width =match_parent
        机器人:layout_alignParentTop =真
        机器人:listSelector =@机器人:彩色/透明
        机器人:stackFromBottom =真
        机器人:layout_above =@ ID / layout_input
        机器人:分隔=#00000000
        />
 

解决方案

问题是,列表视图的选择模式被重置为默认的 CHOICE_MODE_NONE 每时间的列表视图上的方向变化所造成的,因为选择模式尚未明确列表视图布局文件中定义。 Android的源代码在哪里出现这种情况 - <一个href="http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#815" rel="nofollow">http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#815.

该解决方案是增加:

 安卓choiceMode =multipleChoice
 

到列表视图布局。

这也意味着,没有必要手动存储列表视图中选择在的onSaveInstanceState() onViewStateRestored检索()。它是由片段自动完成。因此,删除这两个这些功能。刚开始在操作模式 onResume

  @覆盖
    公共无效onResume(){
        super.onResume();
            getLoaderManager()initLoader(0,空,这一点)。
            如果(myListView.getCheckedItemCount()大于0&安培;&安培; actionMode == NULL){
            actionMode =((ActionBarActivity)getActivity())startSupportActionMode(新ContextualActionBarActionModeCallBack())。
            actionMode.setTitle(myListView.getCheckedItemCount()+选择);
        }
    }
 

注意:如果您已经实现了 LoaderManager.LoaderCallBacks 界面,你只需要改变方向后访问适配器的项目,这样做在 onLoadFinished() onResume()将导致 NPE

I am trying to restore the state of the action mode on orientation change. But it does not work properly. Following the below sequence of steps, in #3 and #4 the selections get corrupted :

  1. Long click an item - item is highlighted, contextual action bar shows with title shows "1 selected". Looks good.
  2. Turn the phone to landscape - no change. Looks good.
  3. Turn the phone back to portrait - item is not highlighted, contextual action bar is gone
  4. Long click an item - item is highlighted, contextual action bar shows with title shows "0 selected"

myListView.getCheckedItemCount() in onSaveInstanceState() returns 0 on #3. That's where the problem starts.

What am i doing wrong in my fragment(using support library)?

@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 layout element :

<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"
        />

解决方案

The issue is that the choice mode of the list view is being reset to a default of CHOICE_MODE_NONE every time the list view is created on orientation change because a choice mode has not been explicitly defined in the list view layout file. The Android source where this happens - http://androidxref.com/4.4.2_r2/xref/frameworks/base/core/java/android/widget/AbsListView.java#815.

The solution is to add :

android:choiceMode="multipleChoice"

to the list view layout.

This also means that there is no need to manually store the list view selections in onSaveInstanceState() and retrieve it in onViewStateRestored(). It is done automatically by the fragment. So remove both these functions. Just start the action mode in 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");
        }
    }

Note : If you have implemented the LoaderManager.LoaderCallBacks interface and you need to access the adaptor items just after orientation change, do it in onLoadFinished() after the adaptor has been loaded with the data source. Doing it in onResume() would cause an NPE.

这篇关于维持方向变化项目选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆