2017-09-13 13 views
1

私はViewPagerを使用していますが、コンテンツ内だけでなく、さまざまなクラスを使用して、多くの異なるFragmentsを表示しています。表示されるリストは動的に変更する必要があります。アイテムを交換して新しいものをアダプタに追加しても(そしてnotifyDataSetChangedと呼んでも)、次のアイテムを変更しようとすると、使用時にスライドされます。mPager.setCurrentItem(mPager.getCurrentItem() + 1);ViewPagerの次のページを動的に変更します

現在の項目と現在の項目の間に新しいFragmentを追加するだけで、アダプタに正しく表示されますが、次の項目が既にプリロードされているので、アダプタのgetItemも呼び出されません。

notifyDataSetChanged」よりも「強い」という別の方法があります。これは、私のViewPagerに、次のアイテムを再度取得するよう指示しますか?


コードサンプル:

追加し、私のFragmentPagerAdapter(サンプルだけではなく、実際のコード)内のアイテムのメソッドを取得

public void add(@NonNull Integer fragmentIndex) { 
    mFragmentOrder.add(fragmentIndex); 
    notifyDataSetChanged(); 
} 

@Override 
public Fragment getItem(int position) { 
    int selectedFragment = mFragmentOrder(position); 
    Fragment fragment; 

    switch (selectedFragment) { 
     case 1: 
      fragment = new FragmentA(); 
      break; 
     case 2: 
      fragment = new FragmentB(); 
      break; 
     case 3: 
      fragment = new FragmentC(); 
      break; 
     default: 
      fragment = new FragmentD(); 
      break; 
    } 

    return fragment; 
} 

これは、次の項目に移動する機能です

public void goToNext() { 
    mPager.setCurrentItem(mPager.getCurrentItem() + 1); 
} 

(私はスワイプすることはできません)

EDITS:

編集1:私はすでに代わりFragmentStatePagerAdapterを使用してOffscreenPageLimit 0に設定しようとしたが、無駄にしていました。

編集2:[解決策] FragmentStatePagerAdapterを使用してを返すために関数getItemPositionを上書きするか、適切な場合にインデックスが問題を解決しました。何らかの理由で、この関数の正しいバージョンを実装した後でさえ、通常のFragmentPagerAdapterは、間違ったFragmentを配信し続けました。

+0

https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html –

+0

私は既に「FragmentStateAdapter」で試していましたが、とにかく問題を解決しませんでした。私が言ったように、 '' ViewPager''は、新しい "次の"スライド用のアダプタを再クエリーしません。既にプリロードされているスライドだけを表示します。オフページの制限を設定しようとしても何もしません。 – Raeglan

答えて

1

デフォルトでは、FragmentPagerAdapterは、アイテムの数と位置が固定されていることを前提としています。したがって、ダイナミズムを導入したい場合は、継承されたアダプタクラスにgetItemPosition(Object object)メソッドを実装して、それを自分で提供する必要があります。非常に基本的な(しかしunefficient)実装はこのようになります:

@Override 
public int getItemPosition(Object object) { 
    return POSITION_NONE; 
} 

親ビューは、その子ビュー(項目)のうちの一つの位置が変更されているかどうかを判断されるたびに、このコードは再作成するフラグメントを強制します。不要なときにレクリエーションを避けたい場合は、メソッドにロジックを含める必要があります。このような何か:

@Override 
public int getItemPosition (Object object) { 
    if (fragmentOrder.indexOf(object) == -1) { 
     return POSITION_NONE; 
    } else { 
     return index; 
    } 
} 

最後に、あなたのフラグメントにonDestroyViewメソッドを追加し、使用しているビューを無効化することにより、可能なメモリリークに注意を払います。

Hereは、2つのPagerAdapterでこれらの問題についての良い議論です。

+0

あなたのソリューションを '' FragmentStateAdapter''と組み合わせることは、そのトリックでした。ありがとう、リンクした記事も便利です。 – Raeglan

関連する問題