简体   繁体   中英

How to restore savedInstanceState of fragment?

I was able to save outState as follows but was unable to restore when I land on this AttendanceFragment.cs second time.

 public override void OnSaveInstanceState(Bundle outState)
    {
        base.OnSaveInstanceState(outState);
        dataGotFromServer = JsonConvert.SerializeObject(dataList);
        outState.PutString(KEY_OUTSTATE, dataGotFromServer);
    }

I tried here to restore but could not get it

 public override void OnViewStateRestored(Bundle savedInstanceState)
    {
        base.OnViewStateRestored(savedInstanceState);
        if(savedInstanceState!=null)
        {
            var result = savedInstanceState.GetString(KEY_OUTSTATE, dataGotFromServer);
        }

    }

and also I tried on CreateView(), OnActivityCreated() and On Create() but unsuccessfull to restore.

And my code for fragment replacement is as

 public void ReplaceFragment(Context context, Fragment newFragment, string TAG)
    {
        Android.Support.V4.App.FragmentManager fragmentManager = ((FragmentActivity)context).SupportFragmentManager;
        Android.Support.V4.App.FragmentTransaction ft = fragmentManager.BeginTransaction();
        ft.Replace(Resource.Id.HomeFrameLayout, newFragment);
        ft.AddToBackStack(TAG);
        ft.Commit();

    }

Edited: This is how I call this fragment

 case (Resource.Id.nav_attendance):


                var role = session.GetUserDetails().Get(SessionManagement.KEY_ROLE).ToString();
                if (role=="Student")
                {
                    Fragment attendanceTabFragment = new AttendanceTabFragment();
                    customFragment.ReplaceFragment(this, attendanceTabFragment,typeof(AttendanceTabFragment).Name);
                }else
                {
                    Fragment attendanceFragment = new AttendanceFragment();
                    customFragment.ReplaceFragment(this, attendanceFragment, typeof(AttendanceFragment).Name);
                }

Any idea or sample code much appreciated. Thank you.

Unless the Activity that contains the Fragment get disposed, Fragment's OnSaveInstanceState is not going to be called.

In a situation were you are swapping Fragments in and out, using Fragment.Arguments is an option instead of a singleton/static var...

re: getArguments / setArguments

In using arguments:

  1. Create a new Bundle in the Fragment constructor and assign it to Arguments
  2. In the OnPause override update the Arguments/Bundle with the items you need to save.
  3. In the OnResume override read the Arguments/Bundle items that you need to restore.

Example Fragment:

public class Fragment1 : Fragment
{
    public Fragment1(System.IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer)
    {
        CreateArgumentBundle();
    }

    public Fragment1()
    {
        CreateArgumentBundle();
    }

    void CreateArgumentBundle()
    {
        Arguments = new Bundle();
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        return inflater.Inflate(Resource.Layout.Frag1, container, false);
    }

    public override void OnPause()
    {
        base.OnPause();
        Arguments.PutString("someKey", "StackOverflow");
    }

    public override void OnResume()
    {
        base.OnResume();
        var someKeyString = Arguments.GetString("someKey", "someDefaultString(new bundle)");
        Log.Debug("SO", someKeyString);
    }
}

In your ReplaceFragment make sure that you are assigning the TAG in the Replace call:

public void ReplaceFragment(Context context, Fragment newFragment, string TAG)
{
    SupportFragmentManager
        .BeginTransaction()
        .Replace(Resource.Id.fragmentContainer, newFragment, TAG)
        .AddToBackStack(TAG)
        .Commit();
}

Before calling your ReplaceFragment , check to see if the Fragment exists ( FindFragmentByTag ) before creating a new one, this example just swaps two fragments in and out and only creates new ones if the manager does not contain one:

button.Click += delegate
{
    toggle = !toggle;
    var frag = SupportFragmentManager.FindFragmentByTag(toggle ? "frag1" : "frag2");
    frag = frag ?? ( toggle ? (Fragment)new Fragment1() : (Fragment)new Fragment2() );
    ReplaceFragment(this, frag, toggle ? "frag1" : "frag2");
};

Note: You will still need to handle the other Fragment lifecycle events in the case that the hosting Activity is recycled:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM