web-dev-qa-db-ja.com

PopBackStackが最初のフラグメントをandroid

私はフラグメントトランザクションに取り組んでおり、バックスタックは次のようになります。

fragA => fragB => fragC => fragD

FragDから戻ってからfragAに戻りたい

fragD => onBackPress => fragA

だから、私は次のようなコードを試しました:

getChildFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

しかし、それはすべてのバックスタックをクリアします、どうすればバックスタックの最初のフラグメントを保持できますか?どうもありがとう

13
user782104

例えば。あなたは以下を行うことができます:

  • fragAをbackStackに追加せずに追加します。だからいつも
    アクティビティ。戻るボタンでは反応しません。
  • fragDを開くときは clear fragment BackStack を実行する必要があります。したがって、Dフラグから戻るボタンを押すと、Aに戻ります。

追伸やりたいことを行う方法は他にもあります。場合によります...

19
Leonidos

「バックスタック」にはスタックのような動作があるので...後入れ先出し...バックスタックに追加した最後のフラグメントが最初にバックスタックからポップされます。独自の動作を指定して、必要な動作を手動で実装する必要があります。 FragmentManagerクラスのメソッドを使用するのはそれほど難しくありません。

フラグメントをトランザクションに追加するときにフラグメントに「タグ」を付けると...

 fragmentTransaction.add(new FragmentA(), "FragmentA_Tag");

後で戻るボタンが押されたときに表示するフラグメントを決定できます...

FragmentA f = fragmentManager.findFragmentByTag("FragmentA_Tag");
if(f != null){
    f.show();
}

どのフラグメントを表示するかをどのように決定するかは完全にあなた次第です。現在表示されているフラグメントを追跡したり、isHiddenクラスの Fragment メソッドを使用したりできます...ところで、私はここでネイティブフラグメントについて話しています。 、ライブラリのフラグメントをサポートしていません。

4
Leo

バックスタックには、フラグメント自体ではなく、トランザクションに関するレコードが含まれています。したがって、最初のトランザクションのレコード(null-> fragA)をバックスタックに追加しないでください。そして、他のすべてのトランザクションのレコードをバックスタックに追加する必要があります。この場合、preformpopBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); Android fragAを除くすべてのフラグメントを削除しました。これは、fragAがどのように追加されたかについてのレコードがないためです。

3
inverse12

ほんの数日前、私はAndroidでフラグメントについて学び始めました。そして私もこの問題に直面しました。ここに私の解決策とこれをどのように解決するかを示します。コードが正しくない場合は修正してください。現在、私たちは何を持っていますか?活動性、多くの断片とそれらのバックスタック。 Drawerメニューからすべてのフラグメントを開き、バックスタックから他のすべてのフラグメントをクリアする必要があります。ただし、ホームフラグメントを1つだけ保持する必要があります。ホームフラグメントにとどまり、ユーザーが[戻る]ボタンを押すと、アプリが終了します。

Activity.class

protected void onCreate(Bundle savedInstanceState)
{
    ...
    // adding Home fragment without adding transaction into backstack
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(R.id.container, HomeFragment.newInstance("args"), null);
    ft.commit();
}

@Override
public void onBackPressed() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        finish();
    }
}

public void addFragmentFromMenu(Fragment fragment){
    String backStateName =  fragment.getClass().getName();
    clearBackStack();
    FragmentManager manager = getSupportFragmentManager();
    if(manager.getBackStackEntryCount()> 0)
    {
        boolean fragmentPopped = manager.popBackStackImmediate(backStateName, 0);

        if (!fragmentPopped && manager.findFragmentByTag(backStateName) == null) {
            //fragment not in back stack, create it.
            addFragment(fragment, manager, backStateName);
        }
    }
    else // no fragments
    {
        addFragment(fragment, manager, backStateName);
    }
}

public void addFragment(Fragment fragment, FragmentManager manager, String backStateName)
{
    FragmentTransaction ft = manager.beginTransaction();
    ft.replace(R.id.container, fragment, backStateName);
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    ft.addToBackStack(backStateName);
    ft.commit();
}

public void clearBackStack() {
    getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

そして引き出しメニューアイテムをクリックして

@Override
public boolean onNavigationItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.nav_camera) {
        addFragmentFromMenu(CameraFragment.newInstance("cam1", "cam2"));
    } else if (id == R.id.nav_gallery) {
        addFragmentFromMenu(TestFragment.newInstance("test1","test2"));
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}
2
Trancer

単語をマークしてください。完全なFragmentTransactionsはフラグメントだけでなくバックスタックに追加されます。つまり、poBackStack()を呼び出す単一のトランザクションでフラグメントを追加および削除した場合でも、完全なトランザクションが逆になります。引数にタグを渡すと、タグ付きトランザクションまですべてのトランザクションがポップされるか、タグ付きトランザクションがポップされます(FragmentManager.POP_BACK_STACK_INCLUSIVEが引数に追加されたため)削除する方法ではなく、追加する方法の詳細です。 フラグメントトランザクションの実行 を参照してください。

0
guneetgstar

私は次のようにしています。すべてのフラグメントをクリアしてから、最初のホームフラグメントを追加します

FragmentManager fm = getActivity().getSupportFragmentManager();
                    fm.popBackStack(Constants.TAG_HOME, FragmentManager.POP_BACK_STACK_INCLUSIVE);

                    ((MainActivity) activity).manageFragment(new HomeFragment(), Constants.TAG_HOME);
 //        write down below function in main activity              
     public void manageFragment(Fragment fragment, String tag) {

            FragmentManager fragmentManager = getSupportFragmentManager();
            if (!fragmentManager.popBackStackImmediate(tag, 0)) {

                FragmentTransaction ft = fragmentManager.beginTransaction();
                ft.add(R.id.content_frame, fragment, tag);
                ft.addToBackStack(tag);
                ft.commit();

            }
        }
0
Rajesh Nasit

1)以下のコードを使用して最初のフラグメントを追加します

Android.support.v4.app.FragmentManager fm = getActivity().getSupportFragmentManager();
        Android.support.v4.app.FragmentTransaction ft=fm.beginTransaction();
        if (fm.findFragmentById(R.id.fragment_container) != null) {
            ft.hide(fm.findFragmentById(R.id.fragment_container));
        }
        ft.add(R.id.fragment_container, new OneFragment(),OneFragment.class.getCanonicalName())
                .addToBackStack(OneFragment.class.getCanonicalName()).commit();

2)以下のコードを使用して、最初のフラグメントから2番目のフラグメントを追加します

Android.support.v4.app.FragmentManager fm = getActivity().getSupportFragmentManager();
                    Android.support.v4.app.FragmentTransaction ft=fm.beginTransaction();
                    if (fm.findFragmentById(R.id.fragment_container) != null) {
                        ft.hide(fm.findFragmentById(R.id.fragment_container));
                    }
                    ft.add(R.id.fragment_container,new TwoFragment(),TwoFragment.class.getCanonicalName())
.addToBackStack(TwoFragment.class.getCanonicalName()).commit();

3)以下のコードを使用して、2番目のフラグメントから3番目のフラグメントを追加します

Android.support.v4.app.FragmentManager fm = getActivity().getSupportFragmentManager();
                Android.support.v4.app.FragmentTransaction ft=fm.beginTransaction();
                if (fm.findFragmentById(R.id.fragment_container) != null) {
                    ft.hide(fm.findFragmentById(R.id.fragment_container));
                }
                ft.add(R.id.fragment_container, new ThreeFragment(),ThreeFragment.class.getCanonicalName())
                        .addToBackStack(ThreeFragment.class.getCanonicalName()).commit();

4)以下のコードを使用して、3番目のフラグメントから4番目のフラグメントを追加します

Android.support.v4.app.FragmentManager fm = getActivity().getSupportFragmentManager();
                Android.support.v4.app.FragmentTransaction ft=fm.beginTransaction();
                if (fm.findFragmentById(R.id.fragment_container) != null) {
                    ft.hide(fm.findFragmentById(R.id.fragment_container));
                }
                ft.add(R.id.fragment_container, new FourFragment(),ThreeFragment.class.getCanonicalName())
                        .addToBackStack(FourFragment.class.getCanonicalName()).commit();

5)onBackPressed()以下のコードを記述してください

@Override
    public void onBackPressed() {
        hideKeyboard(MainActivity.this);
        Fragment currentFragment = this.getSupportFragmentManager().findFragmentById(R.id.fragment_container);

        if (currentFragment.getClass().getName().equalsIgnoreCase(FourFragment.class.getName())) { // Using this code come from third fragment to first fragment
            Fragment f = this.getSupportFragmentManager().findFragmentByTag(TwoFragment.class.getCanonicalName());
            if (f != null) {
                this.getSupportFragmentManager().popBackStackImmediate(f.getClass().getCanonicalName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
            }
        }else {
            super.onBackPressed();
        }
    }
0
user8682667

多くの投稿を調べた後、私はこのようにそれを理解しました:

fragC => fragDメソッドで、2つのトランザクションを実行します。

1クリアバックスタック、fragC => fragA

2 fragA => fragD

しかし、この方法では、fragAの元の状態が破壊される可能性があります。

public static void changeFragCtoD(FragmentManager fm, Fragment fragD){
    fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    FragmentTransaction fragmentTransaction = fm.beginTransaction();
    fragmentTransaction
            .replace(R.id.containerViewId, new fragAClass())
            .commit();

    FragmentTransaction fragmentTransaction = fm.beginTransaction();
    fragmentTransaction
            .replace(R.id.containerViewId, fragD)
            .addToBackStack(fragD.getClass().getName())
            .commit();
}

FragDをもう一度押すと、fragAに戻ります。

0
Fews