web-dev-qa-db-ja.com

フラグメントのViewPagerは、ルートフラグメントが再度置き換えられてもコンテンツを表示しません

fragment screenを含むroot view pagerを含むchild fragmentを実装しています。最初のchild fragmentには、画像を表示するview pagerがあります。

最初はかなりよく表示されますが、root view pagerを含むfragmentが削除されて再度置き換えられた場合(fragment screenの新しいキーワードを使用)、roow view pagerchild fragmentを表示します。

これが私の情報源の一部です。

    @AfterViews // this is the method of fragment screen
    protected void afterViews() {
        api(HotelDetailAPI.class).getProduct("hotels", getArguments().getInt("itemId"), new Callback<Hotel>(this) {
            @Override
            public void success(Hotel _hotel, Response response) {
                hotel = _hotel;
                HotelDetailPagerAdapter adapter = new HotelDetailPagerAdapter(getFragmentManager());
                contentViewPager.setAdapter(adapter);
                contentViewPager.setBackgroundColor(0xffffff);
                super.success(hotel, response);
            }

            @Override
            public void failure(RetrofitError error) {
                super.failure(error);
                LOG.error("failed");
            }
        });
    }


private class HotelDetailPagerAdapter extends FragmentPagerAdapter {
        List<Fragment> fragments = new ArrayList<>();

        public HotelDetailPagerAdapter(FragmentManager fm) {
            super(fm);
            Bundle data = new Bundle();
            data.putSerializable("hotel", hotel);
            Fragment fragment1 = new HotelDetailReservationFragment_();
            Fragment fragment2 = new HotelDetailReservationFragment_();
            Fragment fragment3 = new HotelDetailReservationFragment_();
            fragment1.setArguments(data);
            fragment2.setArguments(data);
            fragment3.setArguments(data);
            fragments.add(fragment1);
            fragments.add(fragment2);
            fragments.add(fragment3);
        }

        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }

        @Override
        public int getCount() {
            return 3;
        }
    }


// this is the first fragment of root view pager it's not shown again.
@EFragment(R.layout.fragment_hotel_detail_reservation)
public class HotelDetailReservationFragment extends BaseFragment {
    private Hotel hotel;

    @AfterViews
    public void afterViews() {
        hotel = (Hotel)getArguments().getSerializable("hotel");
        FragmentTransaction ft = getBaseActivity().getFragmentManager().beginTransaction();
        Fragment fragment = new ImageSliderFragment_();
        Bundle data = new Bundle();
        data.putStringArray("images", hotel.getImages());
        fragment.setArguments(data);
        ft.add(R.id.hotel_detail_image_slider_container, fragment);
        ft.commit();
    }
}

ユーザーが戻るボタンを押すと、fragment screenがバックスタックからポップされます。ユーザーがアイテムをもう一度クリックすると、fragment screen is replacedの新しいインスタンスの何が問題になっていますか?

22
crazy_rudy

私は自分の問題を自分で解決しました。

基本的に、アクティビティのようにフラグメントを使用するデザインは良くありません。 fragment screenを削除して破棄しても、fragment screenの子フラグメントは破棄されません。

私の問題では、最初のfragment screenの子は破棄されなかったため、ページャーアダプターは子を再利用します。これにより、ビューページャーの誤動作が発生します。

この問題にはさまざまな解決策があります。

fragment screenが破棄されるときに、fragment screenのすべての子フラグメントを破棄できます。

または、単にfragment screenActivityに変更します。

私は最後の方法を適用しました、それはうまくいきます:D

楽しい時間をお過ごしください:D私の質問に投票していただきありがとうございます。

4
crazy_rudy

の代わりに :

HotelDetailPagerAdapter adapter = new HotelDetailPagerAdapter(getFragmentManager());

試してください:

HotelDetailPagerAdapter adapter = new HotelDetailPagerAdapter(getChildFragmentManager());

そして

の代わりに :

FragmentTransaction ft = getBaseActivity().getFragmentManager().beginTransaction();

試してください:

FragmentTransaction ft = getChildFragmentManager().beginTransaction();
40
Tiger

問題は、フラグメントがネストされており、getFragmentManager();を使用していることです。代わりにgetChildFragmentManager()を使用する必要があります。

この回答を見る https://stackoverflow.com/a/13391359/1635488

17
android_dev