Fragment的ViewPager在根Fragment再次替换时不显示其内容

22
我正在实现包含根视图页(root view pager)和子片段(child fragment)的碎片屏幕(fragment screen),而其中第一个子片段具有显示图片的视图页(view pager)。
开始时它展示得非常好,但是当包含根视图页的碎片(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();
    }
}
请注意,当用户按下返回按钮时,片段屏幕将从后堆栈中弹出,如果用户再次点击该项,则会替换为新的实例片段屏幕
他们有什么问题吗?

请查看此答案 https://dev59.com/Cp7ha4cB1Zd3GeqPfS_5#52841117 - Rasoul Miri
3个回答

42

代替:

HotelDetailPagerAdapter adapter = new HotelDetailPagerAdapter(getFragmentManager());

尝试:

HotelDetailPagerAdapter adapter = new HotelDetailPagerAdapter(getChildFragmentManager());

而不是:

并且

FragmentTransaction ft = getBaseActivity().getFragmentManager().beginTransaction();
尝试:
FragmentTransaction ft = getChildFragmentManager().beginTransaction();

我已经添加了一个修改。也尝试更改它。 - Tiger
难以置信。我有一个托管ViewPager的片段。我必须传递该ViewPager的适配器getChildFragmentManager,否则什么也不会显示。非常感谢您的帖子。 - j2emanue
1
你救了我的一天。 - Tuan Nguyen
难以置信。对我来说,片段处理非常困难。 - Ahamadullah Saikat
1
非常感谢。你救了我的一天。 - cookieCat

17

是的,在片段中想要显示页适配器时,必须使用getChildFragmentManager()而不是getActivity().getSupportFragmentManager()。 - Vivek Hande

4
我已经自己解决了我的问题。
从根本上讲,使用片段作为活动不是一个好的设计。即使删除和销毁了“片段屏幕”,“片段屏幕”的子片段也不会被销毁。
在我的问题中,第一个“片段屏幕”的子项没有被销毁,所以我的页面适配器重新使用了子项,这导致了视图翻页控件的错误行为。
有各种各样的解决方案可以解决这个问题。
当“片段屏幕”被销毁时,您可以销毁所有子片段。
或者只需将“片段屏幕”更改为“活动”。
我应用了最后一种方法,它运行良好:D
祝你度过愉快的时间:D感谢您对我的问题的投票。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接