Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package androidx.fragment.app;
     18 
     19 import android.content.Context;
     20 import android.os.Bundle;
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 import android.util.Log;
     24 
     25 import androidx.lifecycle.ViewModelStore;
     26 
     27 final class FragmentState implements Parcelable {
     28     final String mClassName;
     29     final int mIndex;
     30     final boolean mFromLayout;
     31     final int mFragmentId;
     32     final int mContainerId;
     33     final String mTag;
     34     final boolean mRetainInstance;
     35     final boolean mDetached;
     36     final Bundle mArguments;
     37     final boolean mHidden;
     38 
     39     Bundle mSavedFragmentState;
     40 
     41     Fragment mInstance;
     42 
     43     FragmentState(Fragment frag) {
     44         mClassName = frag.getClass().getName();
     45         mIndex = frag.mIndex;
     46         mFromLayout = frag.mFromLayout;
     47         mFragmentId = frag.mFragmentId;
     48         mContainerId = frag.mContainerId;
     49         mTag = frag.mTag;
     50         mRetainInstance = frag.mRetainInstance;
     51         mDetached = frag.mDetached;
     52         mArguments = frag.mArguments;
     53         mHidden = frag.mHidden;
     54     }
     55 
     56     FragmentState(Parcel in) {
     57         mClassName = in.readString();
     58         mIndex = in.readInt();
     59         mFromLayout = in.readInt() != 0;
     60         mFragmentId = in.readInt();
     61         mContainerId = in.readInt();
     62         mTag = in.readString();
     63         mRetainInstance = in.readInt() != 0;
     64         mDetached = in.readInt() != 0;
     65         mArguments = in.readBundle();
     66         mHidden = in.readInt() != 0;
     67         mSavedFragmentState = in.readBundle();
     68     }
     69 
     70     public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
     71             Fragment parent, FragmentManagerNonConfig childNonConfig,
     72             ViewModelStore viewModelStore) {
     73         if (mInstance == null) {
     74             final Context context = host.getContext();
     75             if (mArguments != null) {
     76                 mArguments.setClassLoader(context.getClassLoader());
     77             }
     78 
     79             if (container != null) {
     80                 mInstance = container.instantiate(context, mClassName, mArguments);
     81             } else {
     82                 mInstance = Fragment.instantiate(context, mClassName, mArguments);
     83             }
     84 
     85             if (mSavedFragmentState != null) {
     86                 mSavedFragmentState.setClassLoader(context.getClassLoader());
     87                 mInstance.mSavedFragmentState = mSavedFragmentState;
     88             }
     89             mInstance.setIndex(mIndex, parent);
     90             mInstance.mFromLayout = mFromLayout;
     91             mInstance.mRestored = true;
     92             mInstance.mFragmentId = mFragmentId;
     93             mInstance.mContainerId = mContainerId;
     94             mInstance.mTag = mTag;
     95             mInstance.mRetainInstance = mRetainInstance;
     96             mInstance.mDetached = mDetached;
     97             mInstance.mHidden = mHidden;
     98             mInstance.mFragmentManager = host.mFragmentManager;
     99 
    100             if (FragmentManagerImpl.DEBUG) {
    101                 Log.v(FragmentManagerImpl.TAG, "Instantiated fragment " + mInstance);
    102             }
    103         }
    104         mInstance.mChildNonConfig = childNonConfig;
    105         mInstance.mViewModelStore = viewModelStore;
    106         return mInstance;
    107     }
    108 
    109     @Override
    110     public int describeContents() {
    111         return 0;
    112     }
    113 
    114     @Override
    115     public void writeToParcel(Parcel dest, int flags) {
    116         dest.writeString(mClassName);
    117         dest.writeInt(mIndex);
    118         dest.writeInt(mFromLayout ? 1 : 0);
    119         dest.writeInt(mFragmentId);
    120         dest.writeInt(mContainerId);
    121         dest.writeString(mTag);
    122         dest.writeInt(mRetainInstance ? 1 : 0);
    123         dest.writeInt(mDetached ? 1 : 0);
    124         dest.writeBundle(mArguments);
    125         dest.writeInt(mHidden ? 1 : 0);
    126         dest.writeBundle(mSavedFragmentState);
    127     }
    128 
    129     public static final Parcelable.Creator<FragmentState> CREATOR =
    130             new Parcelable.Creator<FragmentState>() {
    131                 @Override
    132                 public FragmentState createFromParcel(Parcel in) {
    133                     return new FragmentState(in);
    134                 }
    135 
    136                 @Override
    137                 public FragmentState[] newArray(int size) {
    138                     return new FragmentState[size];
    139                 }
    140             };
    141 }
    142