簡體   English   中英

按下后退按鈕時如何用片段A替換片段C?

[英]How to replace fragment C with fragment A when back button is pressed?

我的場景:活動 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 替換。實際上,這兩個片段都是可見的。 我該如何解決這個問題?

您需要做兩件事 - 將 FragmentTransaction 從 A->B 命名,然后在包含的活動中覆蓋 onBackPressed() 以在 Fragment 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();
  }
}

理論

使用addToBackStack(tag: String): FragmentTransaction的方法內從FragmentTransaction要回到以標記點。 此方法僅返回用於鏈接能力的FragmentTransaction實例。

然后使用來自FragmentManagerpopBackStackImmediate(tag: String, flag: int): void方法返回。 標簽是您之前指定的。 該標志是常量POP_BACK_STACK_INCLUSIVE以包含標記的事務或0

例子

下面是一個具有以下布局的示例,該布局具有一個 ID 為content_frameFrameLayout ,其中片段被加載到其中。

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

}

當真正實現它時,您可能希望在片段參數上添加一個空檢查;-)。

我就是這樣做的..

使用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();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM