ViewPager中的片段视图在恢复时不会恢复

我有ActionBar标签设置。 它由4个选项卡组成。 一切都很好,直到我离开TabbedFragment并返回。

我创build这样的标签:

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final ActionBar actionBar = getActionBar(); tabs = Lists.newArrayList(); tabs.add(new TabDefinition<>("Tab 1")); tabs.add(new TabDefinition<>("Tab 2")); tabs.add(new TabDefinition<>("Tab 3")); tabs.add(new TabDefinition<>("Tab 4")); for (TabDefinition tab : tabs) { actionBar.addTab(actionBar.newTab() .setText(tab.text) .setTag(tab.tag) .setTabListener(this)); } } 

并像这样初始化适配器:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.paging_tab_container, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); viewPager = (ViewPager) view.findViewById(R.id.pager); viewPager.setAdapter(new FragmentStatePagerAdapter(getFragmentManager()) { @Override public Fragment getItem(int position) { return tabs.get(position).fragment; } @Override public int getCount() { return tabs.size(); } }); viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { getActionBar().setSelectedNavigationItem(position); } }); viewPager.setCurrentItem(getActionBar().getSelectedNavigationIndex(), true); } 

当返回到TabbedFragment选定的选项卡,1旁边将不会有任何内容。 只是空的看法。 但是,如果我select当前+ 2片段内容加载。 然后返回到第一个片段内容重新加载。
例如,我有A,B,C,D标签。 在离开TabbedFragment之前,我select了选项卡A.当返回到TabbedFragment我仍然在选项卡A,但它是空的。 B标签也是
但是当select标签C时,它被创build并加载。 返回到选项卡A重新创build。

这里可能是什么问题?

Solutions Collecting From Web of "ViewPager中的片段视图在恢复时不会恢复"

经过一段时间再次遇到同样的问题,所以更新这个问题。 如果使用FragmentStatePagerAdapter ,则应该通过getChildFragmentManager()而不是getFragmentManager()来提供FragmentManager 。 请参阅Issue 55068:ViewPager在通过后台导航进行导航时不会刷新子片段

好的,所以当使用FragmentStatePagerAdapter时,当你浏览不止一个片段时,你的片段将被销毁。因为默认情况下, offScreenPageLimit默认设置为1,就像上面提到的那样。

通常这个类用于具有非常大的Fragments集合的活动,即,必须滚动浏览大量的视图。 如果您的应用程序不需要超过3-4个选项卡,我build议使用FragmentPagerAdapter ,然后将offScreenPageLimit指定为3,所以如果您到达第四个选项卡,之前的所有3个选项卡仍将保留在内存中。

下面是我创build的github上的一个项目的示例代码,说明了如果不想添加offScreenPageLimit,如何dynamic加载片段。

https://github.com/lt-tibs1984/InterfaceDemo/blob/master/src/com/divshark/interfacedemo/InterfaceDemoMain.java

在这个类中遍历所有这些代码,并且每当我的ViewPager滑过时,您将看到我是如何dynamic加载这些片段的。 最显着的是在底部。

您可以下载此代码,并将其用作您想要执行的testing基础。 尝试在viewPager的onCreate()方法中添加setOffScreenPageLimit(2)并注意不同的行为。 要检查行为,请编辑片段1中的文本。使用此设置导航离开并导航回去。 你会看到它的设置,片段的文本保持你改变它,因为片段不会被重新创build。

如果您有这些问题,请提供其他问题。

祝你好运

UPDATE

 private static final String [] fragmentClasses = {"com.example.project.YourFragment1","com.example.project.YourFragment2","com.example.project.YourFragment3"}; viewPager.setAdapter(new FragmentStatePagerAdapter(getFragmentManager()) { @Override public Fragment getItem(int position) { Fragment fragmentAtPosition = null; // $$$$ This is the Important Part $$$$$ // Check to make sure that your array is not null, size is greater than 0 , current position is greater than equal to 0, and position is less than length if((fragmentClasses != null) && (fragmentClasses.length > 0)&&(position >= 0)&& (position < fragmentClasses.length)) { // Instantiate the Fragment at the current position of the Adapter fragmentAtPosition = Fragment.instantiate(getBaseContext(), fragmentClasses[position]); fragmentAtPosition.setRetainInstance(true); } return fragmentAtPosition; } @Override public int getCount() { return fragmentClasses.length; } }); 

这个问题存在于你用作制表符的碎片中,我想。 他们似乎没有显示任何东西,当他们恢复(见片段生命周期 )。 只有当前选定的+/- 1选项卡为空的“奇怪”问题是因为ViewPageroffScreenPageLimit默认为1。 高于此阈值的所有选项卡都将重新创build。

因此,增加价值 – 在你的情况下 – 将导致所有的标签在恢复后显示为空。 检查你的Fragment代码,你使用哪种生命周期方法来扩大你的布局,设置适配器等,因为这是你的麻烦。

我猜这是因为当加载片段Android加载当前和当前+ 1,如果你debugging你不会看到onPause被调用的直接下一个片段。

您可以通过编程方式在TabHost.OnTabChangeListener的onTabChanged()方法中重新加载内容。

经过多less研究,这对我有效。 我有一个复杂的布局,在片段中有3个选项卡,可以切换为其他片段。 我意识到ViewpagerAdapter将保持状态,即使您按主页button。 我的问题是来回切换会将子片段UI视图元素和崩溃。 关键是不要newViewPagerAdapter 。 添加适配器的空检查为我工作。 此外,请确保为您的需要分配setOffscreenPageLimit() 。 另外,从我了解的setRetainInstance(true); 不应该用于有UI的片段,它是为无头片段而devise的。

在包含您的标签的片段中:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_tab, container, false); tabLayout = (TabLayout) view.findViewById(R.id.tablayout); viewPager = (ViewPager) view.findViewById(R.id.viewPager); //Important!!! Do not fire the existing adapter!! if (viewPagerAdapter == null) { viewPagerAdapter = new ViewPagerAdapter(getChildFragmentManager()); viewPagerAdapter.addFragments(new AFragment(), "A"); viewPagerAdapter.addFragments(new BFragment(), "B"); viewPagerAdapter.addFragments(new CFragment(), "C"); } //Allocate retention buffers for three tabs, mandatory viewPager.setOffscreenPageLimit(3); tabLayout.setupWithViewPager(viewPager); viewPager.setAdapter(viewPagerAdapter); return view; } 

或者更简单地,当导航回tabbedfragment (假设您使用意图和片段是在一个活动内)使用:

 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

这将保持原来的活动,并将其移动到堆栈的顶部,而不是重新创build它,因此您永远不需要重新创buildviewPager。