在片段onCreate方法之前恢复savedInstanceState

时间:2014-09-28 16:01:16

标签: android android-fragments savestate

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

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

因此,当我需要该变量的值时,我在Main Activity中创建了一个公共方法来在片段内调用它。 ((TMainActivity) getActivity()).getTestString()

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

这显然是因为在onRestoreInstanceState片段之后调用了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;
    }

}

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。首先在Activity中调用onCreate,在此方法中,您已经将Bundle与数据一起使用。这意味着您可以恢复活动,然后使用稍后调用的片段onCreateView中的数据。

基本上,您不会覆盖onRestoreInstanceState()方法,而是将其重命名并在“活动”中从onCreate调用它。不重写该方法的原因是因为它将被onCreateLog.v(TAG, "getTestString()=" + ((TMainActivity) getActivity()).getTestString()); 调用2次,然后作为Activity生命周期的一部分。如果在片段中更改了值,则会重置该值。

在您的情况下,您可以移动

onCreate

onCreateViewonRestoreInstanceState

当您恢复大量数据时,这不是一个好的解决方案。您的UI线程将无法恢复活动。但在这种情况下,您可以恢复片段中所需的部分数据,并在.text()中恢复其余部分。