为什么ViewPager会保留它的当前页面,甚至新的实例都已创建?

时间:2015-03-27 16:00:54

标签: android android-fragments android-viewpager

我的情境

假设我有Fragment包含ViewPager,其中有3页(片段)。我的 onCreateView 方法:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.main_tv_fragment, null);
        listFragment = new ArrayList<>();
        listFragment.add(new EventFragment());
        listFragment.add(new ChannelFragment());
        listFragment.add(new FavoriteFragment());
        viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
        fragmentPagerAdapter = new MainLiveTVtAdapter(
                getChildFragmentManager(), listFragment);

        slidingTabLayout = (SlidingTabLayout) rootView.findViewById(R.id.sliding_tabs);
        // Center the tabs in the layout
        slidingTabLayout.setDistributeEvenly(true);
        slidingTabLayout.setCustomTabColorizer(null);
        try {
            viewPager.setAdapter(fragmentPagerAdapter);
        } catch (Exception ex) {
            ex.getMessage();
        }
        slidingTabLayout.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
            @Override
            public int getIndicatorColor(int position) {
                return getActivity().getResources().getColor(R.color.action_bar_bg);
            }
        });
        slidingTabLayout.setViewPager(viewPager);
        viewPager.setOffscreenPageLimit(5);
        viewPager.setAdapter(fragmentPagerAdapter);
        slidingTabLayout.setViewPager(viewPager);
        viewPager.setCurrentItem(page, false);
        return rootView;
    }

我致电viewPager.setCurrentItem(page, false);设置当前页面ViewPager,假设page = 1表示第二页。当片段在窗口中呈现时,第二页显示出来,我将ViewPager滚动到第三页然后用另一个片段替换该片段。之后,我重新创建此片段并将其启用,但ViewPager仍显示第三页甚至viewPager.setCurrentItem(page, false);page = 1调用。

如您所见,ViewPager已创建新实例,Adapter也是。

任何人都可以解释为什么会这样吗?我该如何解决?

修改

Adapter

ViewPager
public class MainLiveTVtAdapter extends FragmentStatePagerAdapter {
    private List<Fragment> fragments;
    private String[] title = {"Sự kiện", "Kênh","Yêu thích"};
    FragmentManager fm;
    public MainLiveTVtAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fm=fm;
        this.fragments = fragments;
    }

    @Override

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

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

    @Override
    public int getCount() {
        return this.fragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return title[position];
    }

//    @Override
//    public void destroyItem(ViewGroup container, int position, Object object) {
//        if (position >= getCount()) fm.beginTransaction().remove((Fragment) object).commit();
//    }
}

3 个答案:

答案 0 :(得分:1)

这就是平台的设计方式。它会尝试在重新创建activity / fragment时保持具有id的视图状态。 ViewPager的位置与EditText的内容保持一致。 如果你想摆脱这个 - 有几种方法:

  • 覆盖onSaveInstanceState并使用您选择的索引调用viewPager.setCurrentItem(),
  • 覆盖onSaveInstanceState并调用viewPager.setAdapter(null),
  • 覆盖onRestoreInstanceState并使用您选择的索引调用viewPager.setCurrentItem()

可能还有其他方法,但通常devs可以保留状态的默认行为。

请注意,如果片段/活动是新添加的并且未重新创建(savedInstanceState等于null),则当前项目将是您在onCreate中设置的项目。

答案 1 :(得分:1)

如果你想用pageradapter做任何动态的东西,你必须像这样实现它:Retrieve a Fragment from a ViewPager 否则会表现得很奇怪。

答案 2 :(得分:0)

这:viewPager.setOffscreenPageLimit(5);是ViewPager保留实例的原因。 doc说:

  

设置应保留在页面两侧的页数   处于空闲状态的视图层次结构中的当前页面。页面超出此范围   在需要时,将从适配器重新创建限制。