在BackPressed上跳过一些片段

时间:2014-09-16 18:28:22

标签: android android-fragments

我对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会出现瞬间出现。

3 个答案:

答案 0 :(得分:8)

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

.addToBackStack(null)

您可以为该特定事务传递字符串标识符,而不是null,例如,Fragment的类名是我们使用的(尽管如果您有多个相同的实例,那么它不会起作用)背板上的片段:

.addToBackStack(Fragment1.class.getName())

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

getFragmentManager().popBackStack(
        Fragment2.class.getName(), 
        FragmentManager.POP_BACK_STACK_INCLUSIVE);

哪个会像预期的那样播放你的动画,但好像它们之间的片段永远不存在。我建议使用 next 片段的原因是因为您可能不希望在后台堆栈上进行第一个片段事务。

答案 1 :(得分:2)

你可以尝试这个,它应该工作,并没有给出瞬间延迟。虽然它不是很漂亮的代码,如果有人有更好的方法,请发帖。

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");

2.在你的frameActivity(活动)中修改你的onBackPressed()"容纳"你的碎片。

@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 :(得分:0)

当您显示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 ...)