127

FragmentPagerAdapterでフラグメントを再利用できません。destroyItem()メソッドを使用すると、フラグメントが削除されますが、getItem()は再度呼び出されません。画像が2〜3しかないため、FragmentStatePagerAdapterの代わりにFragmentPagerAdapterを使用しています。

public class ExamplePagerAdapter extends FragmentPagerAdapter {

    ArrayList < String > urls;
    int size = 0;
    public ExamplePagerAdapter(FragmentManager fm, ArrayList < String > res) {
        super(fm);
        urls = res;
        size = urls.size();
    }

    @Override
    public int getCount() {
        if (urls == null) {
            return 0;
        } else {
            return size;
        }

    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }

    @Override
    public Fragment getItem(int position) {

        Fragment fragment = new FloorPlanFragment();
        Bundle b = new Bundle();
        b.putInt("p", position);
        b.putString("image", urls.get(position));
        Log.i("image", "" + urls.get(position));
        fragment.setArguments(b);
        return fragment;
    }
}

そしてFragmentActivityでは、

pager.setAdapter(new ExamplePagerAdapter(getSupportFragmentManager(), res2)); 
4

7 に答える 7

314

KISS Answer:

FragmentPagerAdapterの代わりにFragmentStatePagerAdapterを使用するだけです。

私は答えを得ました..私は非常にばかげた間違いをしているので、最初にこの質問を削除しようと思いましたが、この答えは、の代わりにFragmentPagerAdapterを使用するのと同じ問題に直面している人を助けますFragmentStatePagerAdapter

@BlackHatSamuraiがコメントで述べたように:

これが機能する理由はFragmentStatePagerAdapter、使用されていないフラグメントとして破棄するためです。FragmentPagerAdapterではない。

于 2012-09-25T12:00:25.473 に答える
171

を使用しても問題は完全には修正されませんでした。これは、ビューページャーで子フラグメントが呼び出されなかっFragmentStatePagerAdapterた場合と同様の問題でした。onCreateView私は実際に自分の内部を別の内部にネストしてFragmentPagerAdapterFragmentいるため、FragmentManagerそれらすべてで共有され、古いフラグメントのインスタンスを保持しています。修正は、代わりに、のインスタンスをホストフラグメント内getChildFragmentManagerののコンストラクターにフィードすることでした。FragmentPagerAdapter何かのようなもの...

FragmentPagerAdapter adapter = new FragmentPagerAdapter(getChildFragmentManager());

このメソッドはフラグメントを介してアクセスできます。これは、特にネストフラグメントが必要な状況で、そのフラグメントgetChildFragmentManager()のプライベートを返すため、私にとってはうまくいきました。FragmentManagerこれが私と同じ問題を抱えているかもしれない誰かに役立つことを願っています!!

  • ただし、APIの最小バージョンを使用getChildFragmentManager()するには、少なくとも17 (4.2)である必要があることに注意してください。これにより、ギアにレンチがかかる可能性があります。もちろん、サポートライブラリv4のフラグメントを使用している場合は、問題ないはずです。
于 2015-04-16T05:33:32.657 に答える
9

オーバーライドlong getItemId (int position)

FragmentPagerAdapterを使用して作成したフラグメントをキャッシュしgetItemます。私は同じ問題に直面していました-呼び出しが呼び出さnotifyDataSetChanged() getItemれていなかった後でも。

これは実際には機能であり、バグではありません。getItemIdフラグメントを正しく再利用できるように、オーバーライドする必要があります。フラグメントを削除しているため、位置が変わります。ドキュメントに記載されているように:

long getItemId (int position)

指定された位置にあるアイテムの一意の識別子を返します。

デフォルトの実装は、指定された位置を返します。アイテムの位置が変更される可能性がある場合は、サブクラスがこのメソッドをオーバーライドする必要があります。

各フラグメントに一意のIDを指定するだけで、完了です。

を使用しFragementStatePagerAdapterたり、戻ったりPOSITION_NONEするのint getItemPosition (Object object)は間違っています。キャッシュは取得されません。

于 2018-02-16T15:17:26.240 に答える
5

@kanikaと@Jraco11が投稿したことを実行しましたが、それでも問題が発生しました。

それで、たくさんの変更の後で、私は私のために働いて、私のFragmentPagerAdapterに次のコードを追加したものを見つけました:

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

私が読んだことによると、getItemPositionは、アイテムを更新するかどうかをViewPagerに通知し、表示位置のアイテムが変更されていない場合に更新を回避するために使用されます。

于 2016-04-28T02:39:41.730 に答える
4

メソッドgetItem()は、新しいアイテムを作成するためにのみ使用されます。それらが作成されると、このメソッドは呼び出されません。アダプタで現在使用されているアイテムを取得する必要がある場合は、次の方法を使用します。

pagerAdapter.instantiateItem(viewPager, TAB_POS)
于 2018-10-30T10:23:08.203 に答える
2

2つの異なるシナリオがあります:1。)すべてのページャーに同じレイアウトがあります:その場合、PagerAdapterによってカスタムアダプターを拡張し、単一のレイアウトを返す方が良いでしょう。

2.)ページャーごとに異なるレイアウトがあります:その場合、FragmentStatePagerAdapterによってカスタムアダプターを拡張し、ページャーごとに異なるフラグメントを返す方がよいでしょう。

于 2015-01-21T09:37:23.280 に答える
0

タブレイアウトにリスナーを設定すると、リスナーの配列ではなく1つのリスナー用のスペースしかないため、これが呼び出されなくなることがわかりましたtabLayout.setOnTabSelectedListener

于 2016-02-04T07:19:29.593 に答える