概要
ViewPagerとFragmentPagerAdapterを使ってFragmentをスワイプ操作で切り替える画面を作ると、デフォルトでは表示しているページの次のページも一緒に読み込むようになっています。
Fragmentの状態遷移でいうと、生成時に1ページ目と2ページ目がonResume
まで呼ばれ、2ページ目に移動したら3ページ目がonResume
まで呼ばます。
そのためFragmentが表示されたタイミングで何かしたい場合はonResume
だと上手くいきません。
解決策
onResume
ではなくsetUserVisibleHint
を使います。
https://developer.android.com/reference/android/support/v4/app/Fragment.html#setUserVisibleHint(boolean)
ViewPagerとFragmentPagerAdapterを使っている場合、setUserVisibleHint
はページの移動が完了した時に呼ばれ、表示中のFragmentでは引数がtrueになり、両隣のFragmentでは引数がfalseになります。
実装はこんな感じです。
public class SamplePageFragment extends Fragment {
....
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// 表示時にさせたい処理を書く
}
}
....
}
注意点
setUserVisibleHint
は新しくページを読み込もうとしたとき(Fragmentを新しく生成するとき)にはonCreate
やonCreateView
よりも先に呼ばれます。
そのためViewの操作をしたい場合は、Viewが生成されているかチェックする必要があります。
例えば表示されたタイミングでWebViewの読み込みをさせたい場合は以下のようにします。
public class SamplePageFragment extends Fragment {
....
private WebView mWebView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_web, container, false);
mWebView = (WebView) view.findViewById(R.id.web);
if (getUserVisibleHint()) {
// onCreateViewが呼ばれたときに、ページが表示中だった
mWebView.loadUrl(getUrl());
}
return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && mWebView != null) {
// ページが表示されて、Viewも生成されたときにURLを読み込む
mWebView.loadUrl(getUrl());
}
}
....
}