Android ViewPager和Fragment序列化

时间:2014-03-25 11:52:00

标签: android serialization android-fragments android-viewpager parcelable

我的活动有两个属性:

  • private Fragment firstFragment;
  • private Fragment secondFragment;

在onCreate方法中:

    adapter = new MyPagerAdapter(getSupportFragmentManager());
    pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);
    pager.setOffscreenPageLimit(6);
    pager.setSaveEnabled(true);

MyPagerAdapter扩展FragmentStatePagerAdapter类。 进入getItem()方法:

    @Override
    public Fragment getItem(int position) {

        Bundle args = new Bundle();

        switch (position) {
            case FIRST:
                secondFragment = new FirstFragment();
                secondFragment.setArguments(args);
                return secondFragment;
            case SECOND:
                secondFragment = new SecondFragment();
                secondFragment.setArguments(args);
                return secondFragment;
        }
    }

并且一切正常。

但是,当我更改屏幕方向时,私有属性设置为null,我丢失了两个片段的引用。 所以我试图将这个片段序列化为:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, FirstFragment.class.getName(), firstFragment);
    getSupportFragmentManager().putFragment(outState, SecondFragment.class.getName(), secondFragment);
}

并使用以下命令将它们加载到onCreate方法中:

    if (savedInstanceState != null) {
        firstFragment = (FirstFragment) getSupportFragmentManager().getFragment(savedInstanceState, FirstFragment.class.getName());
        secondFragment = (SecondFragment) getSupportFragmentManager().getFragment(savedInstanceState, SecondFragment.class.getName());
    }

我的问题:

1。这是将片段序列化为活动屏幕方向更改的正确方法吗?

2。有时候我有错误:“在偏移448处解组未知类型代码55”,它是否可能是由片段序列化造成的?“

编辑:

我需要将片段作为活动属性,因为我有一个监听器接口进入活动:

@Override
public void executeTask(String what) {
    secondFragment.executeTask(what);
}

将此方法调用到firstFragment中。所以FirstFragment可以执行SecondFragment的方法。

2 个答案:

答案 0 :(得分:0)

如果您使用相同的纵向和横向布局,那么当方向更改时,您可以避免重新创建活动。将你的清单改为......

     <activity android:name=".activity.MainActivity"
        android:configChanges="keyboardHidden|orientation|screenSize">
     </activity>

然后覆盖活动中的onConfigurationChanged()...

    @Override
     public void onConfigurationChanged(Configuration        newConfig)
    {
      super.onConfigurationChanged(newConfig);
    }

答案 1 :(得分:0)

我不确定问题的原因是什么,但我会给你一些可能有帮助的提示。

我认为您不应该从Fragments引用Adapter中的Activity。 主要是因为很难同步Activity生命周期,Fragment生命周期和ViewPager儿童生命周期。如果出现任何错误,调试可能会非常痛苦。 相信我,去过那里,做到了......

顺便说一下 - 您是否需要在Fragments中引用Activity

修改

我认为你不应该以{{1​​}}这种方式传递信息。一般情况下,Fragments会自行处理(创建,删除)FragmentManager,而您无法确定这些Fragments是否随时可用。

我认为最好的方法是将数据移动到单独的模型(数据库条目,Fragments或singelton类),然后让{0}知道数据已更改(通过{在SharedPreference中{1}}或只是通过调用Adapter通知DataObserver更新子数据。

实施例

FragmentA ---&gt;听众(Fragments)---&gt;活动---&gt; Adapter -----&gt; fragmentB得到更新

这样一来,如果您想要添加notifyDataChanged或实际上任何数量的reloadData()将使用数据,您不必担心更新任何这些数据 - 只需让它adapter.notifyDataChanged()担心它。