Activity > Fragment > ViewPager > Fragment
という構成にするとViewPager
内のFragment
でonActivityResult
が呼ばれなくなってしまう。
また、Activity
直下にFragment
が複数あると、想定していないFragment
のonActivityResult
が呼ばれてしまう。
例:
Activity > (DrawerFragment + (ParentFragment > ViewPager > ChildFragment))
↑このような構成の時、ViewPager
内のChildFragment
からstartActivityForResult
を呼ぶと、ChildFragment
のonActivityResult
が呼ばれないだけでなく、DrawerFragment
のonActivityResult
が呼ばれてしまったりする。
なお、ParentFragment
のonActivityResult
も呼ばれない。
どのFragment
からActivity
が呼ばれたかは、そのFragment
が属するFragmentManager
内のIndexで管理しているようだ。
ネストされたFragment
からActivity
を呼ぶと、Fragment
のIndexは親Fragment
のFragmentManager
(getChildFragmentManager
で取得するFragmentManager
)から取得される。
しかし、Activity#onActivityResult
で呼び出し元のFragmentを判定する時は、Activity
のFragmentManager
から対応するFragment
を取得しようとするようである。そのため、見当違いのFragment
のonActivityResult
が呼ばれてしまう。
なお、サポートライブラリではそもそも親Fragment
から子Fragment
のonActivityResult
を呼ぶ機能はない模様。
よくわからないFragment
のonActivityResult
が呼ばれてしまう件は、とりあえず無視。そのFragment
にonActivityResult
を実装していなければ問題ないし、実装している場合もきちんと条件分岐していれば問題ない。
子Fragment
のonActivityResult
に関しては、下記のようにして対応する
Fragment
で結果を受け取りたい場合は、親Fragment
のstartActivityForResult
を呼ぶ。Fragment
ではonActivityResult
を受け取れるので、親Fragment
のonActivityResult
内で、すべての子Fragment
のonActivityResult
を手動で呼ぶ// BaseFragment.java
protected void callChildOnActivityResult(FragmentManager fm,
int requestCode, int resultCode, Intent data) {
List<Fragment> fragments = fm.getFragments();
if (fragments != null && fragments.size() > 0) {
for (Fragment fragment : fragments) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
}
上記のようなメソッドを用意し、必要な箇所(親Fragment
のonActivityResult
)で呼ぶとよさげ。
// FooActivity.java
public static void startActivity(Fragment fragment) {
Intent intent = new Intent(fragment.getActivity(), FooActivity.class);
// 親Fragmentがあれば親Fragmentから呼ぶ
Fragment parentFragment = fragment.getParentFragment();
if (parentFragment == null) {
fragment.startActivityForResult(intent, "fragment_content");
} else {
parentFragment.startActivityForResult(intent, "fragment_content");
}
}
Activity
を開始するときはこんな感じ。