ViewPager
フラグメントで使用する場合、タブ間を移動するときにonPause
,メソッドは呼び出されません。onResume
可視化されているか、非表示にされているかをフラグメントで把握する方法はありますか?
残念ながら、位置情報サービスへの登録など、アプリ全体を終了するまで呼び出されないため、タブを切り替えても停止しないロジックがonResume
ありますonPause
。onPause
ViewPager
フラグメントで使用する場合、タブ間を移動するときにonPause
,メソッドは呼び出されません。onResume
可視化されているか、非表示にされているかをフラグメントで把握する方法はありますか?
残念ながら、位置情報サービスへの登録など、アプリ全体を終了するまで呼び出されないため、タブを切り替えても停止しないロジックがonResume
ありますonPause
。onPause
ViewPager にはOnPageChangeListener
インターフェイスが付属しています。以前のページと現在表示されているページにいくつかのフラグを設定することで、この動作をエミュレートできます。
以前の解決策があまり明確ではないことを考えると、ヒントをくれた Phix のおかげで私が解決した方法は次のとおりです。
OnPageChange() コールバックで:
Fragment old_fragment = getActiveFragment(old_position);
Fragment new_fragment = getActiveFragment(new_position);
old_f.setUserVisibleHint(false);
old_f.onPause();
new_f.setUserVisibleHint(true);
new_f.onResume();
次に onResume() で:
if (getUserVisibleHint())
/* resume code */
および onPause() で:
if (!getUserVisibleHint())
/* pause code */
getActiveFragment コードは次のとおりです。これも検索する必要はありません。
return fragmentManager.findFragmentByTag("android:switcher:" + viewPagerId + ":" + position);
注: Fragment には isVisible() メソッドがありますが、あまり一貫性がないように見えるため、UserVisibleHint を使用します。
編集: UserVisibleHint をプライベート フラグに置き換えます。はるかにうまく機能しました!
解決策 1:
以下のように ' アダプターでa を定義SparseArray
します。ViewPagers
この配列では、フラグメントのインスタンスを保持します。
SparseArray<Fragment> registeredFragments = new SparseArray<>();
そしてOverride
あなたのアダプターのinstantiateItem
方法。
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
またOverride
destroyItem
、あなたの方法ViewPagers
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
そして、インスタンスを取得する新しいメソッドを定義しViewPager
Fragments
ます。
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
これで、ロジックを で実装できますViewPager's
OnPageChangeListener
。ビューページャーの を実装する方法の例を次に示しますonPageChangeListener
。
現在の位置を保持する整数を定義します。
int currentPos;
yourViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Empty method
}
@Override
public void onPageSelected(int position) {
// This is paused fragment.
final Fragment pausedFragment = yourAdapter.getRegisteredFragment(currentPos);
// update current position value
currentPos = position;
// This is resumed fragment
final Fragment resumedFragment = yourAdapter.getRegisteredFragment(currentPos);
}
@Override
public void onPageScrollStateChanged(int state) {
// Empty method
}
});
最後に、インスタンスの状態を復元するために、現在の位置を更新して、ユーザーが残した位置を更新し続けますViewPager
currentPos = yourViewPager.getCurrentItem();
解決策 2:
ViewPager
Fragments
別の解決策については、で見つけることができますTag
。次の方法でタグを生成できます。
@NonNull
public static String generateViewPagerFragmentTag(int viewPagerId, int position) {
final StringBuilder tagBuilder = new StringBuilder();
tagBuilder.append("android:switcher:");
tagBuilder.append(viewPagerId);
tagBuilder.append(":");
tagBuilder.append(position);
return tagBuilder.toString();
}
そしてあなたを見つけてくださいFragment
:
final Fragment yourFragment = getSupportFragmentManager().findFragmentByTag(generateViewPagerFragmentTag(R.id.your_viewpager, currentPos));
編集:
ViewPager
数年前、の現在のアイテムを取得するための解決策を探していたときに、 で試してみたところuserVisibleHint
、Fragment
信頼できないことに気付きました。信頼できるかどうかはわかりませんが、今でも使用を避けています。
以下のメソッドを使用できますFragment
public void setUserVisibleHint(boolean isVisibleToUser){
}
の場合isVisibleToUser == true
、フラグメントが表示されます
パーティーには少し遅れましたが、現在のアプリではビューページャーの OffScreenPageLimit を 1 に設定しました。これは、フラグメントがキャッシュされず、ビューが変更されるたびに現在のフラグメントをリロードすることを意味します
savepopulationの回答のメソッドにもう少し定義を与えるには:
yourPager.setOnPageChangeListener(new GridViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int row, int column, float rowOffset, float columnOffset, int rowOffsetPixels, int columnOffsetPixels) {
}
@Override
public void onPageSelected(int row, int column) {
// When on page selected if position is not specific for you
// you can find your fragment or you can switch position.
}
@Override
public void onPageScrollStateChanged(int state) {
}
});