2015-10-07 108 views
1

我有两个片段的TabLayout和ViewPager,它们中的每一个都是从firebase加载数据的recyclerView。在屏幕旋转中保存ViewPager中的片段状态

所有工作正常。但是,当我改变屏幕方向ViewPager重新创建每个片段和片段再次加载数据。

是否有可能以及如何在ViewPager中保存片段状态?

但我不想重写onSaveInstanceState方法来创建数据集,然后恢复它。我想要在查看现有片段时按标签查找片段。

活动

public class MainActivity extends BaseBroadcastActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    mViewPager = (ViewPager) findViewById(R.id.viewpager); 
    setupViewPager(mViewPager); 

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
    tabLayout.setupWithViewPager(mViewPager); 
} 

private void setupViewPager(ViewPager viewPager) { 
    Adapter adapter = new Adapter(getSupportFragmentManager()); 
    adapter.addFragment(MainListFragment.newInstance(connected, "Notices"), "Notices"); 
    adapter.addFragment(MainListFragment.newInstance(connected, "Posts"), "Posts"); 
    viewPager.setAdapter(adapter); 
} 

static class Adapter extends FragmentPagerAdapter { 
    private final List<Fragment> mFragments = new ArrayList<>(); 
    private final List<String> mFragmentTitles = new ArrayList<>(); 

    public Adapter(FragmentManager fm) { 
     super(fm); 
    } 

    public void addFragment(Fragment fragment, String title) { 
     mFragments.add(fragment); 
     mFragmentTitles.add(title); 
    } 

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

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

    @Override 
    public CharSequence getPageTitle(int position) { 
     return mFragmentTitles.get(position); 
    } 
} 

在MainListFragment我只从火力创建recyclerView和负载数据。

谢谢!

编辑

感谢您回复!

我发现我的错误。什么时候我们创建的第一次FragmentPageAdapter的发生,当我们重新创建活动:

  1. FragmentPageAdapter调用instantiateItem方法,它通过标签找到片段和IF段存在的适配器使用,但如果片段不存在适配器调用getItem方法并创建片段。

  2. 在我的情况碎片不会被重建,但数据是令人耳目一新,因为我在片段onCreateView方法刷新他们,但现在我是编辑onCreateView:

    如果(savedInstanceState == NULL){ retrieveData() ; }

回答

0

应该在您在getItem()总是返回新实例的方式来完成。尤其是当你有更多的页面时,我更愿意使用FragmentStatePagerAdapter。 您还需要保存在onSaveInstanceState()中可能丢失的每个内部状态。如果您不想重新加载,则需要保存数据。如果你在POJO中有一些数据,你可以给它们添加Serializable接口,以便将它们轻松地序列化成捆绑。

片段上也有setRetainInstance(),但它总是对我造成一些奇怪的行为,所以我没有使用它。

static class Adapter extends FragmentStatePagerAdapter { 

    public Adapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     Fragment fragment=null; 
     switch (position) { 
      case 0: fragment=MainListFragment.newInstance(mConnected, "Notices"); //don't forget to save mConnected in savedInstanceState 
      case 1: fragment=MainListFragment.newInstance(mConnected, "Posts"); 
     } 
     return fragment; 
    } 

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

    @Override 
    public CharSequence getPageTitle(int position) { 
     String title=""; 
     switch (position) { 
      case 0: title="Notices"; 
      case 1: title="Posts"; 
     } 
     return title; 
    } 
+0

谢谢你,但我知道,我可以节省片段下载的数据,然后将其还原。如果在片段管理器堆栈中找到现有片段并在没有任何其他代码的情况下存在,则可以将其恢复,这很有趣。我认为这是可能的,但我不知道如何。 – jQuick

+0

有一种方法如何从寻呼机获取片段。但它只适用于'FragmentPagerAdapter'。 http://stackoverflow.com/questions/14035090/how-to-get-existing-fragments-when-using-fragmentpageradapter –

0

如果您的片段数据是基于游标可以使用LoaderManager together with a CursorLoader

> ... They automatically reconnect to the last loader's cursor when 
> being recreated after a configuration change. 
> Thus, they don't need to re-query their data. 
相关问题