public Object instantiateItem(ViewGroup container, int position) { if (this.mFragments.size() > position) { Fragment f = (Fragment) this.mFragments.get(position); if (f != null) { return f; } } if (this.mCurTransaction == null) { this.mCurTransaction = this.mFragmentManager.beginTransaction(); } Fragment fragment = getItem(position); if (this.mSavedState.size() > position) { SavedState fss = (SavedState) this.mSavedState.get(position); if (fss != null) { fragment.setInitialSavedState(fss); } } while (this.mFragments.size() <= position) { this.mFragments.add(null); } fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); this.mFragments.set(position, fragment); this.mCurTransaction.add(container.getId(), fragment); return fragment; }
private BackStackEntry(Parcel in) { final ClassLoader loader = getClass().getClassLoader(); fname = in.readString(); args = in.readBundle(loader); switch (in.readInt()) { case NO_STATE: state = null; break; case SAVED_STATE: state = SavedState.CREATOR.createFromParcel(in); break; case PARCELABLE_STATE: state = in.readParcelable(loader); break; default: throw new IllegalStateException(); } }
public void restoreState(Parcelable state, ClassLoader loader) { if (state != null) { Bundle bundle = (Bundle) state; bundle.setClassLoader(loader); Parcelable[] fss = bundle.getParcelableArray("states"); this.mSavedState.clear(); this.mFragments.clear(); if (fss != null) { for (Parcelable parcelable : fss) { this.mSavedState.add((SavedState) parcelable); } } for (String key : bundle.keySet()) { if (key.startsWith("f")) { int index = Integer.parseInt(key.substring(1)); Fragment f = this.mFragmentManager.getFragment(bundle, key); if (f != null) { while (this.mFragments.size() <= index) { this.mFragments.add(null); } f.setMenuVisibility(false); this.mFragments.set(index, f); } else { Log.w(TAG, "Bad fragment at key " + key); } } } } }
public SavedState saveFragmentInstanceState(Fragment fragment) { if (fragment.mIndex < 0) { throwException(new IllegalStateException("Fragment " + fragment + " is not currently in the FragmentManager")); } if (fragment.mState <= 0) { return null; } Bundle result = saveFragmentBasicState(fragment); if (result != null) { return new SavedState(result); } return null; }
@SuppressWarnings("unchecked") public AbstractFragmentPagerAdapter(FragmentManager fragmentManager, int length) { this.fragmentManager = fragmentManager; //É obrigado a saber o tamanho desta forma pq se chamar o getCount() vai dar pau pq a classe filha ainda não atribui nada... Pena que não dá pra fazer nada antes de chamar o super(). this.fragments = (T[]) new Fragment[length]; this.savedStates = new SavedState[length]; }
@Override public Object instantiateItem(ViewGroup container, int position) { //Se já está armazenado em memporia, só recupera. T fragment = fragments[position]; if (fragment != null) { return fragment; } int containerId = container.getId(); if (containerId == View.NO_ID) { throw new IllegalArgumentException("The ViewPager has no id"); } //Cria o fragmento e restaura o estado anterior, se existir. Apenas fragmentos destruídos terão o estado armazenado. String fragmentTag = createFragmentTag(position); fragment = createFragment(position); if (listener != null) { listener.onFragmentCreated(fragment, position); } SavedState savedState = savedStates[position]; if (savedState != null) { fragment.setInitialSavedState(savedState); savedStates[position] = null; } //Adiciona o fragmento na tela, salva-o em memória e faz sua inicialização. FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.add(containerId, fragment, fragmentTag); transaction.commit(); fragments[position] = fragment; internalInitializeFragment(fragment, position); return fragment; }
@Override @SuppressWarnings("unchecked") public void restoreState(Parcelable state, ClassLoader loader) { Bundle bundle = (Bundle) state; bundle.setClassLoader(loader); //Restaura os fragmentos mantidos automaticamente pelo Android. BitSet fragmentPositions = (BitSet) bundle.getSerializable(SAVED_FRAGMENTS_POSITIONS); int nextSetBit = 0; while ((nextSetBit = fragmentPositions.nextSetBit(nextSetBit)) != -1) { int fragmentPosition = nextSetBit++; String fragmentTag = createFragmentTag(fragmentPosition); T fragment = (T) fragmentManager.findFragmentByTag(fragmentTag); //O fragmento deve existir, mas evita que algum problema na sua restauração automática pare a aplicação. if (fragment != null) { fragments[fragmentPosition] = fragment; internalInitializeFragment(fragment, fragmentPosition); } } //Tem que fazer desta forma porque quando a Activity é destruída o array de saved states é recuperado //como Parcelable[], ou seja, o cast pra SavedState[] não funciona. Parcelable[] parcelables = bundle.getParcelableArray(SAVED_STATES); if (BuildConfig.DEBUG && parcelables.length != savedStates.length) { throw new AssertionError(); } for (int i = 0; i < parcelables.length; i++) { savedStates[i] = (SavedState) parcelables[i]; } }
@Override public PerspectiveInstance createFromParcel(Parcel source) { PerspectiveInstance instance = new PerspectiveInstance(source.readInt(), source.readInt(), AndroidBugsUtils.applyWorkaroundForIntentDefaultClassloaderBug(source)); PerspectiveResultRequest resultRequest = AndroidBugsUtils.applyWorkaroundForParcelableDefaultClassloaderBug(source); instance.setResultRequest(resultRequest); SavedState savedState = AndroidBugsUtils.applyWorkaroundForParcelableDefaultClassloaderBug(source); instance.setSavedState(savedState); instance.setHasUnfinishedWork(AndroidBugsUtils.applyWorkaroundForBug5973_read(source)); return instance; }
@NonNull public static BackStackEntry create(@NonNull FragmentManager fm, @NonNull Fragment f) { String fname = f.getClass().getName(); SavedState state = fm.saveFragmentInstanceState(f); Bundle args = f.getArguments(); return new BackStackEntry(fname, state, args); }
@Override public void writeToParcel(Parcel out, int flags) { out.writeString(fname); out.writeBundle(args); if (state == null) { out.writeInt(NO_STATE); } else if (state.getClass() == SavedState.class) { out.writeInt(SAVED_STATE); state.writeToParcel(out, flags); } else { out.writeInt(PARCELABLE_STATE); out.writeParcelable(state, flags); } }
@Override public SavedState saveFragmentInstanceState(Fragment arg0) { return owner.getChildFragmentManager().saveFragmentInstanceState(arg0); }
private void savePerspectiveState(Perspective perspective, PerspectiveInstance perspectiveInstance) { SavedState savedState = getSupportFragmentManager().saveFragmentInstanceState(perspective); perspectiveInstance.setSavedState(savedState); perspectiveInstance.setHasUnfinishedWork(perspective.hasUnfinishedWork()); }
public SavedState getSavedState() { return savedState; }
public void setSavedState(SavedState savedState) { this.savedState = savedState; }
public SavedState m89a(Parcel parcel) { return new SavedState(parcel, null); }
public SavedState[] m90a(int i) { return new SavedState[i]; }
public BackStackEntry(@NonNull String fname, @Nullable SavedState state, @Nullable Bundle args) { this.fname = fname; this.state = state; this.args = args; }
/** * Contorno para o bug: https://code.google.com/p/android/issues/detail?id=37484 * <br> * O {@link android.os.Bundle} do SavedState não fica com o ClassLoader certo depois de ser restaurado de uma activity que foi destruída, * ocasionando em um BadParcelableException -> ClassNotFoundException.<br> * O contorno é setar o ClassLoader correto no SavedState. * * @param savedState SavedState que será ajeitado. * @param context contexto cujo o ClassLoader será colocado no SavedState. */ public static void applyWorkaroundForBug37484(SavedState savedState, Context context) { savedState.mState.setClassLoader(context.getClassLoader()); }
public abstract SavedState saveFragmentInstanceState(Fragment fragment);