Triple Trierarchy Fragment返回导航

时间:2014-01-14 18:05:25

标签: android android-fragments

我有三个片段说GRANDPA,PA,ME。 有一个共同的容器容纳这三个碎片中的一个。

GRANDPA中有按钮,可以调用PA。 同样地,PA中有一个叫ME的按钮。 在ME内部有一个菜单项“DONEtoPA”,它返回PA。 同样,PA“DONEtoGRANDPA”中有一个菜单项,它返回GRANDPA。

除了一个非常小的问题外,一切正常(所有导航)。

对于上述方案,用户可以有三种情况:

情况1:GRADPA呼叫PA和PA呼叫我...用户按下DONEtoPA进入PA然后在PA按下DONEtoGRANDPA并转到GRANDPA。 - 没有问题导航很好。

情况2:GRADPA呼叫PA和PA呼叫我...用户按BACK返回PA然后在PA再次按BACK并转到GRANDPA。 - 没有问题导航很好。

问题情况3:GRADPA呼叫PA和PA呼叫我...用户按下DONEtoPA进入PA然后在PA按BACK。在这里我必须按两次BACK按钮。在第一个BACK按下没有任何反应在第二个BACK按下它进入GRANDPA。

我无法理解为什么需要两次背压。

我使用了addtobackstack(),hide()和show()命令来导航而不是替换()。

代码:GRANDPA

//BUTTON CALLING PA
    gp.setOnClickListener(new OnClickListener()
    {
        public void onClick(View v)
        {
            FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
            ft.hide(this);
            ft.addToBackStack(getTag());
            ft.add(R.id.LLfragmentconsole, new PA(), "PA");
            ft.commit();
        }
    });

代码PA:

//BUTTON CALLING PA
    pa.setOnClickListener(new OnClickListener()
    {
        public void onClick(View v)
        {
            FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
            ft.hide(this);
            ft.addToBackStack(getTag());
            ft.add(R.id.LLfragmentconsole, new ME(), "ME");
            ft.commit();
        }
    });

//MENU ITEM DONEtoGRANDPA
    case R.id.mi_done:
            FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
            ft.remove(this);
            ft.show(getActivity().getSupportFragmentManager().findFragmentByTag("GRANDPA"));
            ft.commit();
   return true;

代码我:

 //MENU ITEM DONEtoPA
    case R.id.mi_done:
            FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
            ft.remove(this);
            ft.show(getActivity().getSupportFragmentManager().findFragmentByTag("PA"));
            ft.commit();
   return true;

据我了解,当我按下DONEtoPA后台记录时,仍然会添加片段ME。因此,当我在PA片段中按BACK(第一次)时,它试图反转这一点,即删除片段ME。但是因为我已经在我的DONEtoPA菜单项中完成了这个点击基本上是浪费了。当我再次按BACK后退堆栈记录更改为PA片段的添加,因此在BACK按下它会反转它,即删除片段PA。

简而言之,我想删除这个双重按压动作。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

创建一个堆栈并使用它来存储您的碎片。然后,您可以在活动中创建这些方法以导航到您的片段层次结构:

显示片段:

private void showFragment(final Fragment fragment) 
{
    if (fragment == null)
        return;

    final FragmentManager fm = getSupportFragmentManager();
    final FragmentTransaction ft = fm.beginTransaction();

    ft.replace(R.id.fragment_layout, fragment);

    ft.commit();

    fragmentStack.push(fragment);
}

推送片段:

public void pushFragment(final Fragment fragment) 
{
    closeKeaboard();

    if (fragment == null)
        return;

    final FragmentManager fm = getSupportFragmentManager();
    final FragmentTransaction ft = fm.beginTransaction();

    ft.setCustomAnimations(R.anim.push_in_anim, R.anim.push_out_anim);

    ft.replace(R.id.fragment_layout, fragment);

    ft.commit();

    fragmentStack.push(fragment);
}

弹出片段:

public void popFragment() 
{
    fragmentStack.pop();

    final Fragment fragment = fragmentStack.peek();

    if (fragment == null)
        return;

    final FragmentManager fm = getSupportFragmentManager();
    final FragmentTransaction ft = fm.beginTransaction();

    ft.setCustomAnimations(R.anim.pop_in_anim, R.anim.pop_out_anim);

    ft.replace(R.id.fragment_layout, fragment);

    ft.commit();
}

然后覆盖OnBackPressed():

@Override
public void onBackPressed() 
{
    if(fragmentStack.size() == 1)
    {
        finish();
        return;
    }

    popFragment();
}

最后你可以这样导航:

pushFragment(this.paFragment);
popFragment();

答案 1 :(得分:0)

我使用popBackStack()得到它。它删除了浪费我点击的backStack条目。

在ME片段中进行以下修改

//MENU ITEM DONEtoPA
case R.id.mi_done:
    FragmentManager fm = getActivity().getSupportFragmentManager();
    fm.popBackStack();

    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
        ft.remove(this);
        ft.show(getActivity().getSupportFragmentManager().findFragmentByTag("PA"));
        ft.commit();
return true;