回退按钮时片段重叠。

8
我已经创建了三个片段,分别是FragmentA、FragmentB和FragmentC,还有一个MainActivity。每个片段中都有一个按钮,点击按钮会将当前片段替换为下一个片段,直到最后一个片段FragmentC。
我将FragmentA替换为FragmentB,然后再替换为FragmentC。
从FragmentA到FragmentB的转换使用以下函数:
    @Override
    public void fragmentreplacewithbackstack(Fragment fragment, String tag) {

        FragmentManager fragmentManager=getSupportFragmentManager();
        FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.contner,fragment , tag);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();   
//      fragmentManager.executePendingTransactions();

    }

从FragmentB到FragmentC的事务使用以下函数

public void fragmentreplace(Fragment fragment,String tag){
        FragmentManager fragmentManager=getSupportFragmentManager();
        FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.contner,fragment , tag);
        fragmentTransaction.commit();   

    }

问题在于当我从FragmentC按下后退按钮时,FragmentC和FragmentA会相互重叠。

如下图所示


以下答案中的解决方案1对我有效:https://dev59.com/CmAg5IYBdhLWcg3ws8vo#32199862 - kp85
4个回答

5
如果您想从这里通过后退键到达Fragment B,则还需要将Fragment C添加到返回堆栈中。因此,也要为Fragment C调用以下方法。
 fragmentTransaction.addToBackStack(null);

编辑 - 更改您当前使用的方法,以从B到C。

public void fragmentreplace(Fragment fragment,String tag){
    FragmentManager fragmentManager=getSupportFragmentManager();
    FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.contner,fragment , tag);
    fragmentTransaction.addToBackStack(null); //this will add it to back stack
    fragmentTransaction.commit();   
}

2
我不想让FragmentB在堆栈中。我希望我的事务直接从FragmentC通过后退按钮返回到FragmentA。 - rajahsekar
那就不要将片段B添加到后退堆栈中。将C添加到后退堆栈中,这样当你按下返回按钮时,它将从后退堆栈中移除,并且你将回到A,因为此时B不再显示。 - Atul O Holic
如何将FragmentC添加到返回栈中。 - rajahsekar
在你的编辑中添加C,并且当你从A到B时,必须删除fragmentTransaction.addToBackStack(null)。 - Atul O Holic
根据上述内容,Fragment C将被添加到后退栈中。addToBackStack将正在发生的事务添加到后退栈中,而不是从中调用的事务。因此,根据您上面的内容,将添加片段C。因此,当您从A到B时,请不要添加它。相反,在从B到C时添加。 - Atul O Holic
显示剩余2条评论

0
为什么不用片段活动和帧布局来替换任何片段框架?
Screen extends FragmentActivity
{
protected void onCreate(Bundle b)
{
    super.onCreate(b);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.work);

            callPerticularScreen(screenNumber,false,null,null);
     }
public void callPerticularScreen(int screenNumber,boolean addToBackStack,String nameTag,Bundle b)
{
    switch(screenNumber)
    {
    case registrationScreen:
        callFragForMiddleScreen(registrationPageFrag,addToBackStack,nameTag);
        break;
    case dashboardScreen:
        callFragForMiddleScreen(dashboardFrag,addToBackStack,nameTag);
        break;
        default:
            break;
    }
}

}

现在,您可以从任何片段屏幕调用此函数,以用另一个片段替换它..比如...

private void callFragForMiddleScreen(Fragment frag,boolean addToBackStack,String nameTag)
{
    transFragMiddleScreen=getFragManager().beginTransaction();
    transFragMiddleScreen.replace(getMiddleFragId(),frag);
    if(addToBackStack)
    {
            transFragMiddleScreen.addToBackStack(nameTag);
    }
    transFragMiddleScreen.commit();
    //getFragManager().executePendingTransactions();
}

从你的片段中调用

Frag1 extends Fragment
{

onActivityCreate()
{
middleScreen=(Screen) getActivity();

middleScreen.callPerticularScreen(1,true,"tag");
}
}

片段活动的布局。

<RelativeLayout
    android:id="@+id/rl2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/rl" >

    <FrameLayout
        android:id="@+id/middle_screen"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </FrameLayout>
</RelativeLayout>

只需不将片段B添加到返回栈中,这样您就可以直接从C返回A。


我正在像这样添加,但是片段C与片段A重叠了。 - rajahsekar
如果您在片段事务中使用替换而不是添加,则片段不能重叠。 - deepak tiwari
当我按下返回按钮时,C片段与A片段重叠。 - rajahsekar
根据上述代码,添加-callPerticularScreen(screenNumber,false,null,null); - 以从B调用您的片段,然后按返回键。 在这里,因此片段B未添加到后堆栈中,因此A将返回。 - deepak tiwari

0

我曾经遇到过同样的问题,Budius这个答案 对我帮助很大。

你可以按照以下方式解决你的问题:

1)实例化以下监听器(你必须保留 FragmentC 实例的引用),由于 fragmentA 是唯一添加到返回栈中的片段,当用户按下返回按钮时,返回栈中的事务数将为零。

private OnBackStackChangedListener backStackChangedListener = new OnBackStackChangedListener() {
    @Override
    public void onBackStackChanged() {
        if(getSupportFragmentManager().getBackStackEntryCount()==0) {
            if(fragmentC!=null) {
                getSupportFragmentManager().beginTransaction().remove(fragmentC).commit();
            }
        }
    }
};

2) 当MainActivity启动时,在其中添加监听器

getSupportFragmentManager().addOnBackStackChangedListener(backStackChangedListener);

3) 当活动停止时,移除监听器


0

25支持库

例如,如果您有

A -> B -> C
A id is 0
B id is 1
C id is 2

要回滚到 A 片段,只需调用

getFragmentManager().popBackStackImmediate(0 /* ID */, 0 /* flag */);

0 - 是回滚返回堆栈条目的ID

或者

popBackStackImmediate(1, FragmentManager.POP_BACK_STACK_INCLUSIVE)

FragmentManager.POP_BACK_STACK_INCLUSIVE,它的意思是你也想要移除提供的ID

同时你也可以调用

getFragmentManager().popBackStackImmediate("stack_name", 0)

"stack_name" 是一个用于回退的后堆栈名称。
例如:
A -> B -> C -> D
A in MAIN_BACK_STACK
B in MAIN_BACK_STACK
C in SEPARATE_BACK_STACK
D in SEPARATE_BACK_STACK

如果你想回到片段B,只需调用

getFragmentManager().popBackStackImmediate("MAIN_BACK_STACK", 0)
or
getFragmentManager().popBackStackImmediate("SEPARATE_BACK_STACK", FragmentManager.POP_BACK_STACK_INCLUSIVE)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接