FragmentのgetChildFragmentManagerメソッドとgetFragmentManagerメソッド



Fragments Getchildfragmentmanager



前提:

このプロジェクトでは、ビューページャーがフラグメントに追加され、ビューページャーがフラグメントに切り替わります。

バグ:

ビューページャーを含むフラグメントを終了し、再入力します。ビューページャーを切り替えるときは、fragmentpageradapterアダプターのgetItem()メソッドを呼び出さないでください。ディスプレイ上で、ビューページャーの表示数が増え、表示データが正しくありません。 (この状況は、フラグメントを初期化するときにのみ必要です。パラメーターを渡す場合)。



デバッグ:

fragmentpageradapterのinstantiateItem(ViewGroup container、int position)メソッドは、呼び出されたときに最適化されます。

public Object instantiateItem(ViewGroup container, int position) { if (mCurTransaction == null) { mCurTransaction = mFragmentManager.beginTransaction() } final long itemId = getItemId(position) // Do we already have this fragment? String name = makeFragmentName(container.getId(), itemId) Fragment fragment = mFragmentManager.findFragmentByTag(name) if (fragment != null) { if (DEBUG) Log.v(TAG, 'Attaching item #' + itemId + ': f=' + fragment) mCurTransaction.attach(fragment) } else { fragment = getItem(position) if (DEBUG) Log.v(TAG, 'Adding item #' + itemId + ': f=' + fragment) mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)) } if (fragment != mCurrentPrimaryItem) { fragment.setMenuVisibility(false) fragment.setUserVisibleHint(false) } return fragment }

上記のコードでは、最初にフラグメントがロードされているかどうかを判別します。ロードされている場合、アタッチ操作のみを実行し、インスタンス化されないため、リソースを節約できます。上記の前提では、デバッグが2回目にフラグメントに入るとき、内部フラグメントを切り替えるときに、mFragmentManager.findFragmentByTag(name)メソッドは値を返さないため、上記のBUGが発生します。 。



解決する:

FragmentPagerAdapterクラスをインスタンス化するときは、2つのパラメーターを渡す必要があります。問題を解決するには、最初のパラメーターをgetFragmentManager()ではなくgetChildFragmentManager()に設定します。

フラグメントソースのgetFragmentManager()の説明:

/** * Return the FragmentManager for interacting with fragments associated * with this fragment's activity. Note that this will be non-null slightly * before {@link #getActivity()}, during the time from when the fragment is * placed in a {@link FragmentTransaction} until it is committed and * attached to its activity. * *

If this Fragment is a child of another Fragment, the FragmentManager * returned here will be the parent's {@link #getChildFragmentManager()}. */ final public FragmentManager getFragmentManager() { return mFragmentManager }

次のように理解できます。
getFragmentManager()は、フラグメントの親コンテナーのフラグメント管理です。
getChildFragmentManager()は、フラグメント内の子コンテナーのフラグメント管理です。



転載:https://www.jianshu.com/p/0668fece6be8