【问题标题】:Fragment incorrectly recreated while rotation旋转时错误地重新创建了片段
【发布时间】:2014-08-22 09:43:50
【问题描述】:

我有一个 FragmentActivity,它通过 ViewPager 显示一些片段。这是我的代码 sn-p,

MyFragmentActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);

    viewPager = (ViewPager) findViewById(R.id.pager);

    fetchDataAsync(this);
}

@Override
private void onDataReceived(List<String> data) {
    viewPager.setAdapter(new MyFragmentPageAdapter(getChildFragmentManager()), data);
}

MyFragmentPagerAdapter

private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
        private Data data;

        public MyFragmentPagerAdapter(FragmentManager fm, Data data)
        {
            super(fm);
            this.data = data;
        }

        @Override
        public Fragment getItem(int position) {
            return MyFragment.newInstance(data.get(position));
        }

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

        @Override
        public CharSequence getPageTitle(int position) {
            return null;
        }
    }

片段由 FragmentPagerAdapter 动态创建并取决于接收到的数据。

当屏幕旋转发生时,我的应用程序崩溃了。通过一些搜索,我了解到“当发生配置更改时,旧的 Fragment 不会被销毁 - 它会在重新创建时将自身添加回活动中”。在那一刻,重新创建的片段的数据为空,因此它在 onCreateView 崩溃。

有人说 FragmentStatePagerAdapter 应该可以工作,但不适用于我的情况。另一个说重用片段而不是重新创建新片段,但 ViewPager 会自动创建它们,我该如何管理。我想永久销毁旧的 Fragments,而不是将它们重新添加到活动中,我该怎么办?

更新

我从 MyFragment 中删除了构造函数参数,并通过 setArgument 传递了它

Bundle b = new Bundle();
b.putString("data", data.toString());
f.setArguments(b);

现在片段可以在重新创建时恢复数据,因为 MyFragment 可以在发生配置更改时以这种方式保存状态(数据)

【问题讨论】:

    标签: android android-fragments android-viewpager android-fragmentactivity


    【解决方案1】:

    您应该自己处理方向更改。

    在配置更改下由开发人员资源覆盖,基本上,这意味着在您的AndroidManifest 中添加属性configChanges="orientation"。然后当方向改变时,Activity.onConfigurationChanged 会被调用。

    参见例如Activity under Configuration Changes

    通常,这个手动句柄会导致你的片段被布局,所以它的大小应该会自动改变。


    另一种解决方案是保持这样:我的意思是,在方向更改时,您的 Activity 正在重新创建,您的Fragment 也是如此。 因此,您需要确保片段中的数据可用,如果不可用,则最终加载它们。

    【讨论】:

    • 感谢您的提示。受第二个解决方案的启发,最终 setRetainInstance 做了简单的把戏。我的片段恰好不在后栈中,所以 setRetainInstance 起作用了。
    • 请查看我的更新,我删除了 setRetainInstance 技巧,并成功恢复了数据
    • 如果你解决了你的问题,请将它作为答案发布然后接受它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多