Restore saveInstanceState to Fragments onCreate method

I made a test application to see how to save InstanceState

.

We now have a main fragment activity and two tabs. I have a variable in Main Activity that it assigns in a method onCreate

.. and I would like to share it with snippets.

So, I created a public method in the main activity to call it inside fragments when I need the value of this variable. ((TMainActivity) getActivity()).getTestString()

The problem is the device is rotated. I got the default for the string, not the stored value.

And this is obvious because it onRestoreInstanceState

is called after the onCreate

fragments.

Now how can I fix this?

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;
    }

}

      

+3


source to share


1 answer


I had the same problem. First called onCreate

in Activity and in this method you already have access to this Bundle with your data. This means that you can restore the Activity and then use the data in a onCreateView

fragment that is called later.

Basically, you don't override the method onRestoreInstanceState()

, but rename it and call it from onCreate

within your activity. The reason not to override this method is because it will be called 2 times - from onCreate

you and then as part of the activity lifecycle. This will reset the value if it was changed in a Fragment.

In your case, you can simply move



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

      

from onCreate

to onCreateView

.

This is not a good solution when you are recovering a large amount of data. Your UI thread would get stuck while restoring the Activity. But in this case, you can restore only part of the data that is needed in the Fragment, and restore the rest to onRestoreInstanceState

.

0


source







All Articles