[解決済み] FragmentPagerAdapterを使用した場合の既存のフラグメントの取得方法
質問
フラグメント同士が通信できるようにするために
Activity
を使用しています。
FragmentPagerAdapter
を接続する際のタブの管理およびすべての詳細を実装するヘルパークラスとして使用されます。
ViewPager
と関連付けられた
TabHost
. 私が実装したのは
FragmentPagerAdapter
は、Android のサンプルプロジェクトで提供されているのと同じように
サポート4Demo
.
主な疑問は、特定のフラグメントを
FragmentManager
から特定のフラグメントを取得することができますか?
FragmentPagerAdapter
はフラグメントを作成し、IdとTagを自動生成します。
どのように解決するのですか?
問題の概要
注意: この回答では、参照する
FragmentPagerAdapter
とそのソースコードを参照するつもりです。しかし、一般的な解決策は
FragmentStatePagerAdapter
.
これを読んでいる人は、おそらくすでに知っていると思いますが
FragmentPagerAdapter
/
FragmentStatePagerAdapter
を作成するためのものです。
Fragments
を作成するためのものです。
ViewPager
が、アクティビティ再作成時(デバイスの回転や、システムがアプリを終了させてメモリを回復させるなど)には、これらの
Fragments
は再び作成されることはなく、代わりにその
から取得されたインスタンスです。
FragmentManager
. では、あなたの
Activity
への参照を取得する必要があるとします。
Fragments
への参照を得る必要があります。あなたは
id
または
tag
これらの作成された
Fragments
というのも
FragmentPagerAdapter
内部で設定する
. そこで問題は、その情報なしにどうやってそれらへの参照を得るかです...。
現在の解決策の問題点:内部コードに依存すること
この質問と似たような質問で私が見た多くの解決策は、既存の
Fragment
を呼び出すことによって
FragmentManager.findFragmentByTag()
を模倣し
という内部で作成されたタグを模倣しています。
"android:switcher:" + viewId + ":" + id
. この問題は、内部のソースコードに依存していることです。ご存知のように、ソースコードは永遠に同じであることが保証されているわけではありません。Google の Android エンジニアは、このソース コードを変更することを簡単に決定できます。
tag
構造を変更することを決定し、その結果、既存の
Fragments
.
内部に依存しない代替案
tag
ここでは、簡単な例として、参照先が
Fragments
が返す
FragmentPagerAdapter
に依存しない、内部の
tags
に設定されている
Fragments
. 重要なのは
instantiateItem()
で、そこにリファレンスを保存します。
の代わりに
の代わりに
getItem()
.
public class SomeActivity extends Activity {
private FragmentA m1stFragment;
private FragmentB m2ndFragment;
// other code in your Activity...
private class CustomPagerAdapter extends FragmentPagerAdapter {
// other code in your custom FragmentPagerAdapter...
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// Do NOT try to save references to the Fragments in getItem(),
// because getItem() is not always called. If the Fragment
// was already created then it will be retrieved from the FragmentManger
// and not here (i.e. getItem() won't be called again).
switch (position) {
case 0:
return new FragmentA();
case 1:
return new FragmentB();
default:
// This should never happen. Always account for each position above
return null;
}
}
// Here we can finally safely save a reference to the created
// Fragment, no matter where it came from (either getItem() or
// FragmentManger). Simply save the returned Fragment from
// super.instantiateItem() into an appropriate reference depending
// on the ViewPager position.
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// save the appropriate reference depending on position
switch (position) {
case 0:
m1stFragment = (FragmentA) createdFragment;
break;
case 1:
m2ndFragment = (FragmentB) createdFragment;
break;
}
return createdFragment;
}
}
public void someMethod() {
// do work on the referenced Fragments, but first check if they
// even exist yet, otherwise you'll get an NPE.
if (m1stFragment != null) {
// m1stFragment.doWork();
}
if (m2ndFragment != null) {
// m2ndFragment.doSomeWorkToo();
}
}
}
または
で動作させたい場合は
tags
へのクラスメンバー変数/参照の代わりに
Fragments
を取得することもできます。
tags
で設定された
FragmentPagerAdapter
を同じように設定します。
注意: これは
FragmentStatePagerAdapter
を設定しないので、これは
tags
を設定しないからです。
Fragments
.
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
// get the tags set by FragmentPagerAdapter
switch (position) {
case 0:
String firstTag = createdFragment.getTag();
break;
case 1:
String secondTag = createdFragment.getTag();
break;
}
// ... save the tags somewhere so you can reference them later
return createdFragment;
}
このメソッドは、内部の
tag
で設定された
FragmentPagerAdapter
によって設定され、代わりにそれらを取得するための適切なAPIを使用します。この方法では、たとえ
tag
が将来のバージョンで変更されたとしても
SupportLibrary
を変更しても、まだ安全です。
忘れないように
のデザインによっては
Activity
は、その
Fragments
はまだ存在しないかもしれないので、それを考慮した上で
null
をチェックすることで、それを考慮する必要があります。
また、もし代わりに
を使用している場合は
FragmentStatePagerAdapter
を使っているのであれば、あなたの
Fragments
へのハードリファレンスは保持しない方がよいでしょう。その代わりに
Fragment
の参照を
WeakReference
への参照は、標準的なものではありません。このように
WeakReference<Fragment> m1stFragment = new WeakReference<Fragment>(createdFragment);
// ...and access them like so
Fragment firstFragment = m1stFragment.get();
if (firstFragment != null) {
// reference hasn't been cleared yet; do work...
}
関連
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み] Androidで画面の大きさをピクセル単位で取得する方法
-
[解決済み] なぜフラグメントなのか、そしてアクティビティの代わりにフラグメントを使用するのはどんなときか?
-
[解決済み] ViewPagerとフラグメント - フラグメントの状態を保存する正しい方法は何ですか?
-
[解決済み】FragmentPagerAdapterとFragmentStatePagerAdapterの違いは何ですか?
-
[解決済み】ViewPagerを動的に更新しますか?
-
[解決済み] ArrayAdapter<myClass> の使用方法
-
[解決済み] Androidのソースコードにある@hideの意味とは?
-
[解決済み] 「KotlinとAndroidで「パラメータTを推測するのに十分な情報がありません。
-
[解決済み] DialogFragmentを正しく終了させるには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】ビューページャーで現在のFragmentインスタンスを取得する
-
[解決済み] ViewPagerの一部であるListFragmentのデータを更新する
-
[解決済み] android: imageview の画像を画面に合わせて伸縮させる
-
[解決済み] ArrayAdapter<myClass> の使用方法
-
[解決済み] AndroidでラジオボタンにOnClickListenerを設定するには?
-
[解決済み] wrap_contentでRelativeLayoutがフルスクリーンになってしまう
-
[解決済み] DialogFragmentを正しく終了させるには?
-
[解決済み] Studio 3.4 をアップデートしたら、引数の leftShift() メソッドが見つかりませんでした。
-
[解決済み] 文字サイズとアンドロイドの画面サイズの違い
-
[解決済み] アンドロイドのdatepickerダイアログで最大の日付を設定するには?