Android 跳过一些反压的片段

Android 跳过一些反压的片段,android,android-fragments,Android,Android Fragments,我是一个全新的android碎片,所以请容忍我 我有一堆使用单个活动作为主机的片段 在我看来,我的片段是按部分分组的,尽管它们仍然是模块化的/代码可重用的。 考虑这个期望的场景: Frag1->(按下一步)->Frag2->(按下一步)->Frag3->(按后)->Frag1 在浏览了一系列片段之后,我想在按下后退按钮时跳过前面的一些片段(在本场景中,跳过片段2) 然而,在我当前的代码中,我的问题是,即使返回到Frag1,Frag3也不会从屏幕上消失。发生的情况是Frag1和Frag3在彼此的顶

我是一个全新的android碎片,所以请容忍我

我有一堆使用单个活动作为主机的片段

在我看来,我的片段是按部分分组的,尽管它们仍然是模块化的/代码可重用的。 考虑这个期望的场景:

Frag1->(按下一步)->Frag2->(按下一步)->Frag3->(按后)->Frag1

在浏览了一系列片段之后,我想在按下后退按钮时跳过前面的一些片段(在本场景中,跳过片段2)

然而,在我当前的代码中,我的问题是,即使返回到Frag1,Frag3也不会从屏幕上消失。发生的情况是Frag1和Frag3在彼此的顶部都可见

以下是我的相关代码片段:

用于创建Frag1的代码片段

@Override
public void onNavigationDrawerItemSelected(int position) {
    // update the main content by replacing fragments
    // init the fragment (with a default fragment, not null)
    Fragment fragment = PlaceholderFragment.newInstance(position + 1);
    // Position number from navigation sidebar starts from 0.
    // Since position starts from 0, add 1 to match section number
    // as implemented in {@link #onSectionAttached()}
    switch(position) {
        case 0:
            fragment = PlaceholderFragment.newInstance(position + 1);
            break;
        case 1: // Frag1 case
            fragment = new AddPointsFragment().newInstance(position + 1, "");
            break;
        default:
            break;
    }
    // update the main content by replacing fragments
    FragmentManager fragmentManager = getFragmentManager();
    // clear all fragments from previous section from the back stack
    fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    // replace all currently added fragments in container and replace with the new fragment
    fragmentManager.beginTransaction()
            .replace(R.id.container, fragment)
            .commit();
}
用于创建Frag2的代码片段

public void onEnterButtonFragmentInteraction(int sectionNumber, String cardNo) {
    // TODO: Add point for given card number
    int points = 5; //sample points
    AddPointsSuccessFragment addPointsSuccessFragment =
            new AddPointsSuccessFragment().newInstance(sectionNumber, cardNo, points);
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.container, addPointsSuccessFragment)
            .addToBackStack(null)
            .commit();
}
用于创建Frag3的代码片段

public void onOkButtonFragmentInteraction(int sectionNumber, String cardNo, int points) {
    RedeemRewardFragment redeemRewardFragment =
                new RedeemRewardFragment().newInstance(sectionNumber, cardNo, points);
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.container, redeemRewardFragment);
        fragmentTransaction.commit();
}
我目前的解决方法是在创建Frag3并运行此代码时添加
.addToBackStack(null)

public void onBackButtonFragmentInteraction() {
    this.onBackPressed(); // simulate pressing of activity back button
    FragmentManager fragmentmanager = getFragmentManager();
    fragmentmanager.popBackStack(); // pop Frag2 from back stack
}

就在调用onBackPressed()方法之后。不幸的是,这种解决方法很难看,因为在进入Frag1之前,Frag2会在瞬间出现。

您可以尝试这种方法,它应该可以工作,并且不会在瞬间延迟。虽然它的代码并不漂亮,如果有人有更好的方法,请发布

1.给你的碎片贴上标签

transaction.add(R.id.main_activity_container, FirstFragment, "FirstFragment");
transaction.replace(R.id.main_activity_container, Second, "SECOND");
transaction.replace(R.id.main_activity_container, Third, "THIRD");
@Override
public void onBackPressed() {
    // TODO Auto-generated method stub

    int lastStack = getSupportFragmentManager().getBackStackEntryCount();
    try {
        //If the last fragment was named/tagged "three"
        if (getSupportFragmentManager().getFragments().get(lastStack).getTag().equalsIgnoreCase("THIRD")){

            getSupportFragmentManager().popBackStackImmediate();
            getSupportFragmentManager().popBackStackImmediate();

            //Get your first fragment that you loaded in the beginning. 
            Fragment first = getSupportFragmentManager().findFragmentByTag("FirstFragment");
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.main_activity_container, first);
            transaction.commit();
            return;
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    super.onBackPressed();
}
2.在frameActivity(activity)中修改onBackPressed()以“容纳”片段

transaction.add(R.id.main_activity_container, FirstFragment, "FirstFragment");
transaction.replace(R.id.main_activity_container, Second, "SECOND");
transaction.replace(R.id.main_activity_container, Third, "THIRD");
@Override
public void onBackPressed() {
    // TODO Auto-generated method stub

    int lastStack = getSupportFragmentManager().getBackStackEntryCount();
    try {
        //If the last fragment was named/tagged "three"
        if (getSupportFragmentManager().getFragments().get(lastStack).getTag().equalsIgnoreCase("THIRD")){

            getSupportFragmentManager().popBackStackImmediate();
            getSupportFragmentManager().popBackStackImmediate();

            //Get your first fragment that you loaded in the beginning. 
            Fragment first = getSupportFragmentManager().findFragmentByTag("FirstFragment");
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.main_activity_container, first);
            transaction.commit();
            return;
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    super.onBackPressed();
}

所以你的解决方案的关键是这个家伙:

.addToBackStack(null)
您可以传递该特定事务的字符串标识符,而不是null——例如,片段的类名就是我们使用的名称(尽管如果在backbackback上有同一片段的多个实例,则这不起作用):

然后,如果您想从
Fragment3
返回
Fragment1
,只需使用下一个片段的标识符弹出,并传递
INCLUSIVE
标志(这意味着它还将弹出您指定的下一个片段):


它将按预期播放动画,但中间的片段似乎从未出现过。我建议使用下一个片段的原因是,您可能不希望第一个片段事务位于后堆栈上

显示Frag2时,请使用:

final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(FRAG_2);
fragmentTransaction.replace(containerID, frag2, FRAG2_TAG);
背面印刷:

@Override
public void onBackPressed() {
   final Frag2 frag2 = (Frag2)getSupportFragmentManager().findFragmentByTag(FRAG2_TAG);
   if (frag2 != null && frag2.isVisible() && getSupportFragmentManager().getBackStackEntryCount() > 0) {
    getSupportFragmentManager().popBackStackImmediate();
    return;
   }
}
这将防止在调用onBackPressed()后显示frag2。
避免使用popBackStack(),因为这将导致frag2生命周期触发(onCreate、onStart、onResume…)

我尝试了您的建议,但不幸的是,在返回Frag1之前,屏幕仍会在瞬间显示frag2。我还添加了Frag1的代码片段,以获得更好的透视图:(经过进一步的实验,我发现在实施了你的建议后,我不应该再称这个为.onBackPressed()。现在它可以工作了“…好像中间的碎片从来没有出现过。”谢谢!;)我也遵循了同样的方法,但它对我不起作用,请检查我在这里做错了什么我如何移动Frag3→按导航返回按钮导致的碎片1?如果碎片超过3个,则此方法无效。出于感谢您的回答,我尝试执行您的建议。虽然我花了一些时间来实现,但它确实奏效了!虽然我还是更喜欢@kcopock的答案,因为它对我来说需要更少的代码更改和混乱。不过,你给了我另外一个可能的想法,我还要加分!:)是的,KCopock的答案可能是最好的,看起来更干净。也许我会在我的应用程序中使用类似的解决方案:P。尽管它们的工作方式可能有点不同?如果您再次转到:Frag1->Frag2->Frag3->BackBtn而不是BackBtn,它将如何运行?是退出还是转到Frag2如果您指的是kcopock的建议,那么它将退出应用程序,因为它遵循了我想要的流程。Frag1->Next->Frag2->Next->Frag3->Back->Frag1->Back->EXIT