簡體   English   中英

片段Backstack

[英]Fragment Backstack

嗨,我有一個活動和三個片段。 當我替換我的第一個片段時,我將它添加到backstack中。

FragmentTransaction fragmentTransaction = getFragmentManager()
            .beginTransaction();
fragmentTransaction.replace(R.id.authentication_parent0_linear,
                new LoginFragment(), LOGINTAG);
fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();

但是當我在另外兩個片段之間移動時,我沒有將它們添加到backstack中。所以每當我從其他兩個片段按回來時,我需要回到第一個片段。當我刪除第一個片段並添加第二個片段或刪除時它工作正常首先添加第三個,即當我按下時,我將回到第一個片段。 但是當我在這兩個片段之間導航時,會刪除第二個並添加第三個或刪除第三個並添加第二個等。 在那個例子,當我按下我退出應用程序並且backstackcount顯示為零但是我第一次刪除第一個片段時將其存儲在backstack中。

getFragmentManager()
            .beginTransaction()
            .replace(R.id.authentication_parent0_linear,
                    new SignupFragment(), SIGNUPTAG).commit();

所以我的問題是片段backstack會在提交之間重置。 如果是這樣,我怎樣才能第一次在后台堆疊中獲取存儲的片段

實現你想要的最好方法是不使用fragment的backstack。

  1. 不要在任何地方使用addToBackStack()
  2. 在實例字段mLoginFragment中保留第一個片段LoginFragment引用。 添加第一個片段將如下所示(可能在activity的onCreate()

      FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); mLoginFragment = new LoginFragment(); fragmentTransaction.replace(R.id.authentication_parent0_linear, mLoginFragment, LOGINTAG); fragmentTransaction.commit(); 
  3. 在您的活動中重寫onBackPressed()方法如下:

     @Override public void onBackPressed() { Fragment fr = getFragmentManager().findFragmentById(R.id.authentication_parent0_linear); // chek that mLoginFragment!=null, basically this should never happen! if (fr == mLoginFragment) { super.onBackPressed(); } else { FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.authentication_parent0_linear, mLoginFragment, LOGINTAG); fragmentTransaction.commit(); } } 

使用背板可以通過一種麻煩的方式來達到預期的效果。 方法如下:

  1. 創建片段A時不要調用addToBAckStack()
  2. 從片段A導航到B或C或其他片段時, 調用 addToBackStack()
  3. 當從B更深地導航到C等時,在事務之前調用popBackStack() 可以在SO上找到它的說明。 像這樣:

     getFragmentManager().popBackStack(); FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.authentication_parent0_linear, new FragmentC(), "whatever"); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); 

片段管理器允許您將名稱(或TAG)放在給定狀態。 如果將相同的名稱傳遞給popBackStack,它將彈出狀態直到達到該狀態。 例如

// Add initial fragment
getFragmentManager()
    .beginTransaction();
    .replace(R.id.authentication_parent0_linear, new LoginFragment());
    .addToBackStack(TAG_FIRST_FRAGMENT_STATE) // The key is not passing null here
    .commit();

// Add other fragments like such
getFragmentManager()
    .beginTransaction();
    .replace(R.id.authentication_parent0_linear, new SignupFragment());
    .addToBackStack(null)
    .commit();


// On back press
@Override
public void onBackPressed() {
    FragmentManager fragmentManager = getFragmentManager();
    if (fragmentManager.getBackStackEntryCount() > 1) {
        fragmentManager.popBackStack(TAG_FIRST_FRAGMENT_STATE, 0);
    } else {
        super.onBackPress();
    }
}

我最終想通了。 基於Kirill K答案

    public class MainActivity extends Activity implements OnClickAuthentication,
    LoginInterface, SignupInterface {

FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    fragmentManager = getFragmentManager();
    Fragment fragment = fragmentManager.findFragmentByTag("one");
    if (fragment == null) {
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction
                .replace(R.id.relative, new OneFragment(), "one");
        fragmentTransaction.commit();
    }
}

@Override
public void onClickAuthButton(int flag) {
    if (flag == 2) {
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction
                .replace(R.id.relative, new TwoFragment(), "two");
        fragmentTransaction.commit();
    } else {
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.relative, new ThreeFragment(),
                "three");
        fragmentTransaction.commit();

    }

}

@Override
public void switchToSignup() {
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction
            .replace(R.id.relative, new ThreeFragment(), "three");
    fragmentTransaction.commit();

}

@Override
public void switchToLogin() {
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.relative, new TwoFragment(), "two");
    fragmentTransaction.commit();

}

@Override
public void onBackPressed() {
    Fragment twoFragment = fragmentManager.findFragmentByTag("two");
    Fragment threeFragment = fragmentManager.findFragmentByTag("three");
    if ((twoFragment != null && twoFragment.isVisible())
            || (threeFragment != null && threeFragment.isVisible())) {
        fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction
                .replace(R.id.relative, new OneFragment(), "one");
        fragmentTransaction.commit();
    } else {
        super.onBackPressed();
    }
}

}

我這樣做了

1.全局聲明fragmentManager變量:

FragmentManager fm = getFragmentManager();

2.onCreate方法在不使用backstack的情況下加載第一個片段

fm.beginTransaction().replace(R.id.content_frame , new main_fragment()).commit();

3.現在當你要添加新的片段然后創建一個方法,它將檢查片段是否已經在backstack中,並且它還將處理單擊相同的片段事件(如果你在導航抽屜中使用frag)

void replaceFragment (Fragment fragment) {
    Fragment current = fm.findFragmentById(R.id.content_frame);
    //Check if that frag is already opened
    if (!current.getClass().equals(fragment.getClass())) {


        String backStateName = fragment.getClass().getName();

        boolean fragmentPopped = fm.popBackStackImmediate(backStateName, 0);

        if (!fragmentPopped) {

            //fragment is not in back stack,so add it.
            FragmentTransaction ft = fm.beginTransaction();
            ft.replace(R.id.content_frame, fragment);
            ft.addToBackStack(backStateName);
            ft.commit();

        }
    }
    else {
        //if fragmentPopped is true then it will auto pop up the fragment
        //so we dnt have to do anything here     
    }
}

4.現在只需將你的片段類傳遞給

replaceFragment(new yourfragment());

5.現在處理背壓

public void onBackPressed() {

    int backStackEntryCount = fm.getBackStackEntryCount();


       if (backStackEntryCount == 0) {
            new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle("Closing Activity")
                    .setMessage("Are you sure you want to close this Application?")
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                            System.exit(0);
                        }

                    })
                    .setNegativeButton("No", null)
                    .setOnCancelListener(new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialogInterface) {
                               //backpress over alert dialog
                                finish();
                                System.exit(0);
                        }
                    })
                    .show();

        } else {


            super.onBackPressed();
        }


    }

希望這個能對您有所幫助

暫無
暫無

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

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