在方向更改时保留列表片段中的列表

Posted

技术标签:

【中文标题】在方向更改时保留列表片段中的列表【英文标题】:Retaining list in list fragment on orientation change 【发布时间】:2012-05-14 20:49:24 【问题描述】:

我有一个使用片段的应用程序,所有片段都包含在一个活动中。活动以包含按钮菜单的片段开始,所有这些都会导致各种列表片段替换原始按钮/菜单片段。

我的问题是,在方向改变时,如果活动正在显示其中一个列表视图,它会消失并且按钮菜单会返回。我理解为什么会发生这种情况......活动被破坏并重新创建,但不知道如何解决它并通过方向更改来维护列表视图/当前片段。

我找到了setRetainInstance 和使用here 的示例,但我不知道如何将它应用到我的情况与按钮菜单或我想保留的片段可能是一个几个不同的。

下面是简化代码以显示主要活动和列表片段之一。

非常感谢任何关于添加内容的指针,以便保留列表片段。

活动

public class Main extends FragmentActivity 
    private MainMenuFragment menu;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        menu = new MainMenuFragment();
        getSupportFragmentManager().beginTransaction().replace(R.id.pane, menu).commit();    
    

列表片段

public class ItemListFragment extends ListFragment 

    private TextView header;
    private TextView empty;
    private Button add;
    public static Cursor itemCursor;
    private GroceryDB mDbHelper;
    public static long mRowId;
    public static CheckCursorAdapter lists;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 
        View v = inflater.inflate(R.layout.common_list, container, false);
        header = (TextView) v.findViewById(R.id.header);
        empty = (TextView) v.findViewById(android.R.id.empty);
        header.setText(R.string.header_item);
        empty.setText(R.string.empty_items);
        return v;
    

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);

        mRowId=0;
        mDbHelper = new GroceryDB(getActivity());
        mDbHelper.open();

        itemCursor = mDbHelper.fetchAllItems();
        getActivity().startManagingCursor(itemCursor);

        String[] from = new String[]  GroceryDB.ITEM_NAME ;
        int[] to = new int[]  R.id.ListItem ;
        lists = new CheckCursorAdapter(getActivity(),
                R.layout.listlayout_itemlist, itemCursor, from, to);
        setListAdapter(lists);        
    

【问题讨论】:

【参考方案1】:

如何解决它并通过方向更改来维护列表视图/当前片段

每次调用onCreate() 时,您都在盲目地替换片段。相反,仅当savedInstanceState()null 时才添加/替换片段。如果不是null,那么您将从配置更改中恢复过来,并且您现有的片段将被重新创建(或者,如果它们被保留,它们已经存在)。

setRetainInstance(true) 表示片段本身将在配置更改时保留,而不是像活动一样被销毁/重新创建。但是,它仍将使用onCreateView() 调用。在您的代码中,这意味着 ItemListFragment 的数据成员将保留,但即使您不重新查询数据库,您仍需要调用 setListAdapter()

【讨论】:

嗯,这真是令人难以置信的尴尬(更不用说我的愚蠢了)。我知道我应该检查savedInstanceState(),但出于某种原因,我这次没有这样做,甚至从未考虑过。感谢您的快速回复。【参考方案2】:

我知道这个问题很久以前就已经解决了,但是为了寻找解决方案的人,我想补充一下您还可以使用一个自定义类来保存您的列表适配器的数据列表。

这样它在重新创建活动(和列表片段)时保留数据,您可以测试它是否在您的 oncreate 中有任何数据。如果list == nulllist.size < 0 您照常进行,并以您通常获取的任何方式获取数据。否则,您只需使用它已有的数据设置您的 listadapter。

对我来说这要容易得多,并且在创建 android 主/详细流项目时,Eclipse 会自动为您的数据创建一个类似的 DummyContent 类,它基本上只需要更改您的 listfragment 的 oncreate。

【讨论】:

以上是关于在方向更改时保留列表片段中的列表的主要内容,如果未能解决你的问题,请参考以下文章

方向更改时,片段视图为空

在方向更改时恢复列表视图中的项目和滚动位置

如何防止在方向更改时重新创建片段寻呼机中的片段?

android片段在方向更改时创建了两次

Android中的方向更改时,列表视图会被清除(使用customAdapter,List )

方向更改后片段中的 getActivity() 为空