7

我有一个Activity包含三个 Fragments 的片段,我们称它们为ABCFragment A在 Activity 中被调用onCreate()

FragmentA fragA = new FragmentA();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.activity2_layout, fragA, "A");
transaction.commit();

并在按下某些按钮时被 Fragment BCaddToBackStack()替换,并且 FragmentTransaction 调用.

FragmentB fragB = new FragmentB(); //or C
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.activity2_layout, fragB, "B");  //or C
transaction.addToBackStack("B"); //or C
transaction.commit();

但是假设我连续调用Fragment B三次,我怎样才能防止它自己堆叠到它上面呢?同时我希望这成为可能:B调用 > C调用 > B调用 - 但是当我尝试返回时,我希望B只打开一次(C < B)而不是(B < C < B) . 所以基本上用新的 backStack 删除第一个 backStack。

4

2 回答 2

13

来自How to resume Fragment from BackStack if exists,这可能与您的查询非常相似。

有一种方法可以根据事务名称或提交提供的 id 弹出回栈(例如,使用已提到的片段的类名,如 Thijs):

String backStateName = fragment.getClass().getName();

添加到后台:

FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();

弹出时:

getSupportFragmentManager().popBackStackImmediate (backStateName, 0); 

因此,在替换片段之前,我们可以检查 backstack 中的存在性,例如:

boolean fragmentPopped = manager.popBackStackImmediate (backStateName, 0);

if (!fragmentPopped){ //fragment not in back stack, create it.
    ...
    ...
    ft.addToBackStack(backStateName);
    ft.commit();
}

请检查上述问题和接受的答案以获得更多解释。

于 2015-11-18T05:27:40.753 回答
1

我已经解决了您的一个问题,即how can I prevent it from stacking on to it self?不久前在我自己的一个项目中。这是我在那里使用的确切代码:

public void setContent(@NonNull Fragment fragment, boolean addToBackStack) {
    Fragment current = getSupportFragmentManager().findFragmentById(R.id.main_content);
    if (current == null || !current.getClass().equals(fragment.getClass())) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (addToBackStack) {
            transaction.addToBackStack(null).add(R.id.main_content, fragment).commit();
        } else {
            transaction.replace(R.id.main_content, fragment).commit();
        }
    }
}

这段代码的作用是检查当前显示的 Fragment 是什么类,并将其与要替换它的 Fragment 进行比较。如果它们相同,它不会做任何事情。此代码可以按照您的需要进行调整,如下所示

Fragment newFragment = new FragmentB(); //OR FragmentC
Fragment current = getSupportFragmentManager().findFragmentById(R.id.activity2_layout);
if (!current.getClass().equals(newFragment.getClass())) {

    //POP BACKSTACK HERE LIKE EXPLAINED BELOW

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    final String tag = newFragment.getClass().getSimpleName();
    transaction.addToBackStack(tag);
    transaction.add(R.id.activity2_layout, newFragment, tag);
    transaction.commit();
} else {
    //THROW AN ERROR OR SOMETHING, HANDLE IT BEING THE SAME
}

确保一次只存在一个特定类型的片段可以通过弹出回栈直到相同片段第一次出现之前来实现。我没有为此编写任何代码,但实现该功能应该不会太难。如果您自己无法弄清楚,请告诉我,我会尝试为您写一个示例:)

于 2015-11-17T14:18:46.070 回答