web-dev-qa-db-ja.com

フラグメントを前面に移動(フラグメントの再作成なし)

3つのフラグメントF1 F2 F3 F4があります。すべてサイドバーからアクセスできます。

4つすべてはいつでも、どのような順序でも呼び出すことができます。

F1が既にクリックされている(作成されている)場合は、F1を二度と作成せず、フラグメントマネージャーを使用してフラグメントF1のみを前面に戻します。他のすべてのフラグメントについても同じです =

これまでのところ私はすべてのフラグメントに対してこれを試しました私のコンテナで(フラグメントアクティビティ)

if (fragmentManager.findFragmentByTag("apps")==null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

Fragment newFragment = new CategoriesFragment();
transaction.replace(R.id.content_frame, newFragment, "apps");
transaction.addToBackStack("apps");
transaction.commit();   
} else{

}

Ifパーツを使用すると、フラグメントが再作成されない(既に作成されている場合)ことが確実になりますが、elseパーツに何を書き込んですでに作成されたフラグメントをビューの前面に表示できるか)階層

助けてください、私はこれに2日間行き詰っています。

24
Nitin Misra

私はこのコードをアクティビティクラスに配置します。これにはFrameLayout with id R.id.fragment_containerが必要です。

_private Fragment1 F1;
private Fragment2 F2;
private Fragment3 F3;
private Fragment4 F4;       

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    F1 = new Fragment1();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F1).commit();
    F2 = new Fragment2();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F2).commit();
    F3 = new Fragment3();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F3).commit();
    F4 = new Fragment4();
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, F4).commit();

    //if needed show F1
    getSupportFragmentManager().beginTransaction().show(F1).commit();

}
_

そして、ボタンクリックのためにこれを追加します:

_public void onBtnClick(View view){
    if(mShowF1){
        getSupportFragmentManager().beginTransaction().show(F1).commit();
        getSupportFragmentManager().beginTransaction().hide(F2).commit();
        getSupportFragmentManager().beginTransaction().hide(F3).commit();
        getSupportFragmentManager().beginTransaction().hide(F4).commit();
    }
    //...
}
_

ボタンをクリックすると、必要なフラグメントを表示したり、他のフラグメントを非表示にしたりできます。

注(@ developer1011):アクティビティの保存後に使用する場合は、commitAllowingStateLoss ()を呼び出します。フラグメントはアクティビティの復元では復元されないため、注意して使用してください。

注: MainActivityは、フラグメントごとにOnFragmentInteractionListenerを実装する必要があります。

_public class MainActivity extends FragmentActivity implements Fragment1.OnFragmentInteractionListener, Fragment2.OnFragmentInteractionListener, Fragment3.OnFragmentInteractionListener, Fragment4.OnFragmentInteractionListener {//..

    @Override
    public void onFragmentInteraction(Uri uri) {
        //
    }
}
_
10
Solata

タグでフラグメントを取得し、コンテナで置き換えます。

else{
Fragment existingFragment = (CategoriesFragment)fragmentManager.findFragmentByTag("apps");
transaction.replace(R.id.content_frame,existingFragment, "apps");
transaction.addToBackStack("apps");
transaction.commit();
}

更新:「transaction.replace()」を使用する代わりに、フラグメントの非表示と表示を使用して再作成を回避できます。

fragmentTransaction.hide(<oldFragment>);
fragmentTransaction.show(<newFragment>);
6
nikvs

Fragmentを再作成することを心配せずに単に追加しようとしているのであれば、私がFragmentを追加するために書いたこのメソッドはあなたの仕事をするでしょう。

public static void attachFragment ( int fragmentHolderLayoutId, Fragment fragment, Context context, String tag ) {


    FragmentManager manager = ( (AppCompatActivity) context ).getSupportFragmentManager ();
    manager.findFragmentByTag ( tag );
    FragmentTransaction ft = manager.beginTransaction ();

    if (manager.findFragmentByTag ( tag ) == null) { // No fragment in backStack with same tag..
        ft.add ( fragmentHolderLayoutId, fragment, tag );
        ft.addToBackStack ( tag );
        ft.commit ();
    }
    else {
        ft.show ( manager.findFragmentByTag ( tag ) ).commit ();
    }
}
3
erluxman
  1. フラグメントに単純な_ArrayList<Fragment>_を使用し、それらを順番に追加して、get(0)がF1を取得し、get(1)がF2を取得するなどを確認します。

  2. フラグメントをシングルトンとして作成します。各フラグメントに、静的フィールドとメソッドを追加します。

    _ private static Fragment mMyInstance = null;
    
     public static Fragment newInstance() {
         if (mMyInstance == null) {
             mMyInstance = new F1();
         }
         return mMyInstance;
     }
    _
  3. StaticメソッドでFragmentsを作成し、ArrayListに追加します。

  4. 各フラグメントで、setRetainInstance(true);コマンドをonCreate()メソッドに追加します。

FragmentManagerでFragmentを追加すると、onCreate()は初めて呼び出されるだけですが、onCreateView()は毎回呼び出されます。設定を変更したためにアクティビティが再作成された場合に備えて、毎回ビューをインフレートしてウィジェットをワイヤリングしたいとします。ただし、追加したものをチェックして、それが初めてかどうかを確認し、そうでない場合はウィジェットを以前の状態にリセットできます。そのため、状態を追跡するには、フラグメントにメンバー変数が必要です。 onStop()をオーバーライドして状態を保存し、ウィジェットを関連付けた後、onCreateView()で再適用します。

次に、サイドバーボタンを押すと、そのボタンに対応するフラグメントが取得され、前のフラグメントが削除され、現在のフラグメントがFragmentManagerで追加されます(または、remov()/ add()ではなくreplace()コマンドを使用します)。 。

1
Rick Falck

サポートフラグメントを使用している場合、この静的メソッドが機能します。

    /**
 * Takes a Fragment TAG and tries to find the fragment in the manager if it exists and bring it to front.
 * if not, will return false;
 * @param manager
 * @param tag
 */
public static boolean resurfaceFragment(FragmentManager manager, String tag ){
    Fragment fragment = manager.findFragmentByTag(tag);
    FragmentTransaction transaction = manager.beginTransaction();
    if (fragment!=null){
        for (int i = 0; i < manager.getFragments().size(); i++) {
            Fragment f =  manager.getFragments().get(i);
            transaction.hide(f);

        }
        transaction.show(fragment).commit();
        return true;
    }

    return false;
}
0
JDenais