android - 在 Fragments onCreate 方法之前恢复 savedInstanceState

标签 android android-fragments savestate

我制作了一个测试应用程序,以便了解如何保存 InstanceState

现在我们有一个 Main Fragment Activity 和两个 Tab Fragment。我在主 Activity 中有一个变量,它的值位于 onCreate 方法中。我想与 fragment 共享它。

因此,我在主 Activity 中创建了一个公共(public)方法,以便在我需要该变量的值时在 fragment 中调用它。 ((TMainActivity) getActivity()).getTestString()

问题是当设备旋转时我得到了字符串的默认值而不是保存的值。

这显然是因为 onRestoreInstanceState 在 fragment 的 onCreate 之后被调用。

现在,我该如何解决这个问题?

TMainActivity.java

public class TMainActivity extends FragmentActivity {

    final private static String TAG = "TMainActivity";
    final private static String EXTRA_TEST = "MAIN_KEY";

    private CollectionPagerAdapter mCollectionPagerAdapter;
    private ViewPager mainPager;

    private String test = "Default";

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

        Log.v(TAG, "onCreate() Before test= " + test);

        if (savedInstanceState == null) {
            test = "New";
        } else {
            test = savedInstanceState.getString(EXTRA_TEST) + " - Restored";
        }

        Log.v(TAG, "onCreate() After test= " + test);

        mainPager = (ViewPager) findViewById(R.id.main_pager);

        mCollectionPagerAdapter = new CollectionPagerAdapter(getSupportFragmentManager());
        mainPager.setAdapter(mCollectionPagerAdapter);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        Log.v(TAG, "onSaveInstanceState()");

        outState.putString(EXTRA_TEST, test);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        Log.v(TAG, "onRestoreInstanceState()");
        Log.v(TAG, "onRestoreInstanceState() savedInstanceState=" + (savedInstanceState != null));

        test = savedInstanceState.getString(EXTRA_TEST);
    }

    public String getTestString() {
        return test;
    }

    private class CollectionPagerAdapter extends FragmentStatePagerAdapter {
        public CollectionPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int i) {
            Fragment fragment = null;

            switch (i) {
            case 0:
                fragment = new Tab1Fragment();
                break;
            case 1:
                fragment = new Tab2Fragment();
                break;
            }

            return fragment;
        }

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

        @Override
        public CharSequence getPageTitle(int position) {
            return "OBJECT " + (position + 1);
        }
    }

}

Tab1Fragment.java

public class Tab1Fragment extends Fragment {

    final private static String TAG = "Tab1Fragment";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.v(TAG, "onCreate()");
        Log.v(TAG, "getTestString()=" + ((TMainActivity) getActivity()).getTestString());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main_tab1, container, false);
        return rootView;
    }

}

Tab2Fragment.java

public class Tab2Fragment extends Fragment {

    final private static String TAG = "Tab2Fragment";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.v(TAG, "onCreate()");
        Log.v(TAG, "getTestString()=" + ((TMainActivity) getActivity()).getTestString());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main_tab2, container, false);

        return rootView;
    }

}

最佳答案

我刚刚遇到了同样的问题。首先在 Activity 中调用 onCreate 并且在此方法中您已经可以使用该 Bundle 和您的数据。这意味着您可以恢复 Activity,然后使用稍后调用的 Fragment 的 onCreateView 中的数据。

基本上您不会重写onRestoreInstanceState() 方法,而是重命名它并从您的Activity 中的onCreate 调用它。不覆盖该方法的原因是因为它会被调用 2 次 — 从 onCreate 开始由您调用,然后作为 Activity 生命周期的一部分。如果 fragment 中的值发生更改,这将重置该值。

在你的情况下你可以移动

Log.v(TAG, "getTestString()=" + ((TMainActivity) getActivity()).getTestString());

onCreateonCreateView

当您恢复大量数据时,这不是一个好的解决方案。您的 UI 线程会在恢复 Activity 时卡住。但在这种情况下,您可以只恢复 Fragment 中所需的部分数据,而将其余部分恢复到 onRestoreInstanceState 中。

关于android - 在 Fragments onCreate 方法之前恢复 savedInstanceState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26086769/

相关文章:

java - Android JSON 解析问题

android - 如何在 Android 中单击 ImageView 时从一个 fragment 移动到另一个 fragment ?

android - 将 100 个 Activity 应用程序移植到 Fragments 而不死

android - 在 Android 谷歌地图 v2 上保存标记

android - 如何使用共享首选项

android - aSmack 即服务

java - 如何访问Fragment类中的setAdapter?

java - 如何以编程方式创建约束布局

c++ - 使用getline解析和存储变量

java - 使用 webviewfragment 更改方向时如何保存 webview 的状态