如何在按下后退按钮后重新创建前ListFragment的列表视图

时间:2013-02-07 00:35:45

标签: android android-listview android-fragments android-listfragment fragmenttransaction

我有一个ListFragment,其中包含一个listview,它包含一个导航结构。通过选择列表的项目,应显示下一个导航层次结构阶段。等等。

下一个层次结构阶段由一个新片段创建(删除旧片段并通过使用addToBackStack通过碎片事务添加相同的片段),其中新列表视图的arrayadapter更新为下一个导航层次结构的项目。这工作很好。

我希望用户可以通过后退按钮导航回来。在这里开始我的问题。我不知道如何保存listview,因此可以在使用后退按钮后重新创建它。

我认为使用onSaveInstanceState会是一个好主意。但是当事务被调用时,不会调用onSaveInstanceState。我通过在方法中放置一个Log.d(“..”,“...”)来检查它。它没有被调用。(我发现,当从纵向旋转到横向时,调用onSaveInstanceState)查看,反之亦然。但这对我的问题没有帮助。)

那么最好的想法是存储listview的元素并在使用后退按钮后重新创建listview并创建前一个片段?所有项都是存储在绑定到ListAdapter的ArrayList中的字符串。


这是我的代码。我实现了一个接口,通过点击listview中的项目调用parent-activity中的方法。在这个方法中,我首先调用一个方法来填充已经存在的ArrayList(navigationsItems),其中包含下一个导航阶段内容的新项目:

我的ArrayAdapter的代码:

arrayAdapterFuerNaviList = new ArrayAdapter<String>(
        BRC_BoardOverviewActivity.this,
        android.R.layout.simple_list_item_1, 
                    navigationsItems);

在这个方法中,我首先调用一个方法来填充ArrayList(navigationsItems),其中包含下一个导航阶段的项目:

// load new itemlist to navigation-
public void inhaltAktuelleNaviListeInArrayLaden() {

    navigationsItems.clear();
    for (int i = 0; i < prefs.getInt("aktuelleNaviListe_size", 0); i++) {
        (...)
        navigationsItems.add(titel);
    }
}

然后我调用该方法,用它加载新的ListFragment并将新的ArrayAdapter绑定到它:

// push navifragment to BackStack and create a new instance of it
public void naviFragmenteNeuLaden() {

            // get a reference to the actual ListFragment
    Fragment removefragment = frgm.findFragmentById(R.id.navi_container);

    // initialize ne ListFragment
    BRC_NavigationsFragment navifragment = (BRC_NavigationsFragment) frgm
            .findFragmentById(R.id.navi_container);

    // remove the old and bind the new ListFragment from/to the container ...
    FragmentTransaction frgmta = frgm.beginTransaction();
    frgmta.remove(removefragment);
    frgmta.add(R.id.navi_container, navifragment);

    // ... push the old ListFragment on the BackStack and commit ...
    frgmta.addToBackStack(null);
    frgmta.commit();
    frgm.executePendingTransactions();

    // ... bind the updated ArrayAdapter to the new ListFragment ...
    try {
        navifragment.setListAdapter(arrayAdapterFuerNaviList);
    } catch (Exception e) {
        // TODO 
        e.printStackTrace();
    }

    // ... and notify 
    try {
        arrayAdapterFuerNaviList.notifyDataSetChanged();
    } catch (Exception e) {
        // TODO 
        e.printStackTrace();
    }
}

如前所述,前向导航没有问题。但当我按下后退按钮时在第二个导航阶段,前一个ListFragment被加载(使用Log.d(“...”。“...)进行验证 - ListFragment的onCreatView()中的消息),但其中的前一个列表视图不是创造了。


我目前正在研究一种新方法。当您单击列表中的项目时,我将当前列表以及对当前ListFragment的引用写入基于矢量的堆栈。然后我抓住“onBackPressed()” - 按下后退按钮的方法。所以现在当按下按钮时,我调用已经提到的方法(见上文),将堆栈中的项目数据写回列表,通过存储的引用调用form ListFragmt并将更新的ArrayAdapter绑定到它。这实际上是在进行中。完成后我会写出这种方法的结果。

1 个答案:

答案 0 :(得分:1)

我解决了这个问题。

对于ListView的不同导航内容,我定义了一个类“Naviliste”,其中存储了所有项目。如果有人点击某个项目,则会生成一个包含相应新列表的新列表视图。这些列表已编制索引,因此每个列表都会获得一个固定的ID。

通过单击ListView中的项目,当前Naviliste的ID将被压入堆栈。之后,将创建一个新片段绑定到它的新列表。如果用户更进一步,则重复相同的过程,等等......

如果用户按下后退按钮后退,则完成以下操作:

通过放置在父活动中的onPressedBack()方法捕获后退按钮。通过这种方法,可以调用自己的方法。这会将最后一个ID推入堆栈,然后在新创建的片段中使用它构建前一个列表。

与此同时,我将沿着一个计数器运行,该计数器计算我的导航深度。在每个导航步骤中,它将被升级为1.并且反过来减少1.使用此计数器,我能够查询用户是否在导航根(计数器= 0)并再次按下后退按钮离开当前的活动。如果是这样,我调用finish()并关闭其片段的父活动。瞧!

效果很好。花了一点时间来克服它。但现在我很高兴我的解决方案有效。 :)