我的场景:活动1由片段A->组成。 B-> C.使用以下代码添加所有片段:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content, fragment, TAG);
ft.addToBackStack(TAG);
ft.commit();
现在,从片段C开始,我想直接返回片段A.因此,我在添加片段C时评论了ft.addToBackStack(TAG)
。所以当我从CI按下后退按钮时,直接在屏幕上显示片段A.
但是,片段C不会被A替换。实际上,这两个片段都是可见的。我该如何解决这个问题?
答案 0 :(得分:28)
你需要做两件事 - 从A-> B命名FragmentTransaction,然后在你的包含活动中覆盖onBackPressed(),当你在片段C上时调用FragmentManager#popBackStack (String name, int flags)。例如:
从A-> B转换
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, new FragmentB(), "FragmentB")
.addToBackStack("A_B_TAG")
.commit();
从B-> C过渡将使用与“FragmentC”作为其标记的类似交易。
然后在你的包含Activity覆盖onBackPressed():
@Override
public void onBackPressed() {
if (getSupportFragmentManager().findFragmentByTag("FragmentC") != null) {
// I'm viewing Fragment C
getSupportFragmentManager().popBackStack("A_B_TAG",
FragmentManager.POP_BACK_STACK_INCLUSIVE);
} else {
super.onBackPressed();
}
}
答案 1 :(得分:17)
<强>理论强>
使用FragmentTransaction
中的addToBackStack(tag:String):FragmentTransaction
方法标记您要返回的点。 此方法仅返回链接能力的FragmentTransaction
实例。
然后使用FragmentManager
中的popBackStackImmediate(tag:String,flag:int):void
方法返回。标签是您之前指定的。该标志是常量POP_BACK_STACK_INCLUSIVE
以包含标记的事务或0
。
示例强>
以下是具有以下布局的示例,其中FrameLayout
的ID为content_frame
,其中片段被加载到其中。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<FrameLayout
android:id="@+id/content_frame"
android:layout_below="@id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
下面的代码在用id content_frame
替换布局元素的内容时用它的片段类名标记一个片段。
public void loadFragment(final Fragment fragment) {
// create a transaction for transition here
final FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
// put the fragment in place
transaction.replace(R.id.content_frame, fragment);
// this is the part that will cause a fragment to be added to backstack,
// this way we can return to it at any time using this tag
transaction.addToBackStack(fragment.getClass().getName());
transaction.commit();
}
并且要完成此示例,该方法允许您在加载标记时使用标记返回到完全相同的片段。
public void backToFragment(final Fragment fragment) {
// go back to something that was added to the backstack
getSupportFragmentManager().popBackStackImmediate(
fragment.getClass().getName(), 0);
// use 0 or the below constant as flag parameter
// FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
实现这一点时,您可能希望在片段参数上添加空检查; - )。
答案 2 :(得分:0)
这就是我的方法。
带有 FragmentA.java 和其他任何片段。
用其类名作为标签替换片段:
private void showFragment(Fragment fragment){
if(fragment != null){
getSupportFragmentManager().beginTransaction().replace(R.id.container,fragment,fragment.getClass().getSimpleName()).commit();
}
}
现在在onBackPressed()中:
@Override
public void onBackPressed()
{
if(getSupportFragmentManager().findFragmentByTag("FragmentA") == null)
showFragment(new FragmentA());
else
super.onBackPressed();
}