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);
注:フラグメントにはisVisible()メソッドがありますが、あまり一貫性がないように見えるため、UserVisibleHintを使用します。
編集:UserVisibleHintをプライベートフラグに置き換えます。ずっとうまくいった!
UがAndroid Support Library(rev 11)を使用している場合、getUserVisibleHint()を使用するか、または setUserVisibleHint() をオーバーライドして、表示される変更をキャプチャして非表示にできます。 投稿 。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// do something when visible.
}
}
解決策1:
以下のように、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
のFragments
を試してみましたが、信頼できないことに気付きました。信頼できるかどうかは今はわかりませんが、使用することは避けています。
Fragment
で以下のメソッドを使用できます
public void setUserVisibleHint(boolean isVisibleToUser){
}
いつ isVisibleToUser == true
、フラグメントが表示されます
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) {
}
});
パーティーに少し遅れましたが、現在のアプリではビューページャーのOffScreenPageLimitを1に設定しています。これは、フラグメントがキャッシュされず、ビューが変更されるたびに現在のフラグメントがリロードされることを意味します