Android 当片段setRetainInstance(true)时未调用View.onRestoreInstance(当片段位于后堆栈中时,双屏方向会更改)

Android 当片段setRetainInstance(true)时未调用View.onRestoreInstance(当片段位于后堆栈中时,双屏方向会更改),android,android-fragments,android-view,Android,Android Fragments,Android View,我有两个碎片:一个在另一个上面。片段在其构造函数中具有setRetainInstancetrue 当我做一个双屏翻转并按back键时,顶部碎片弹出,底部碎片可见。但底部片段的视图不接收onRestoreInstanceState 当我删除setRetainInstancetrue时,一切正常。但是我需要setRetainInstancetrue来处理多个线程,所以我无法解决这么简单的问题 如何保证在这种情况下调用onRestoreInstanceState 下面是一些示例代码: package

我有两个碎片:一个在另一个上面。片段在其构造函数中具有setRetainInstancetrue

当我做一个双屏翻转并按back键时,顶部碎片弹出,底部碎片可见。但底部片段的视图不接收onRestoreInstanceState

当我删除setRetainInstancetrue时,一切正常。但是我需要setRetainInstancetrue来处理多个线程,所以我无法解决这么简单的问题

如何保证在这种情况下调用onRestoreInstanceState

下面是一些示例代码:

package com.example.saverestoreviewstate;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction().replace(android.R.id.content, new Fragment1()).commit();
        }
    }

    public static class SaveRestoreView extends TextView {

        public SaveRestoreView(Context context) {
            super(context);
        }

        String value;

        public void setValue(String value) {
            this.value = value;
            setText(value);
        }

        @Override
        public Parcelable onSaveInstanceState() {
            Bundle bundle = new Bundle();
            bundle.putParcelable("super", super.onSaveInstanceState());
            bundle.putString("value", value);
            return bundle;
        }

        @Override
        public void onRestoreInstanceState(Parcelable state) {
            Bundle bundle = (Bundle)state;
            super.onRestoreInstanceState(bundle.getParcelable("super"));
            value = bundle.getString("value");
            setText(value);
        }
    }

    public static class Fragment1 extends Fragment {

        private static boolean firstRun = true;

        public Fragment1() {
            setRetainInstance(true);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            Context context = inflater.getContext();

            LinearLayout layout = new LinearLayout(context);
            layout.setId(12);
            layout.setOrientation(LinearLayout.VERTICAL);

            SaveRestoreView saveRestore = new SaveRestoreView(context);
            saveRestore.setId(128);

            if (firstRun) {
                saveRestore.setValue("*******save this string*******");
                firstRun = false;
            }

            layout.addView(saveRestore);

            Button button = new Button(inflater.getContext());
            button.setText("Create 2nd fragment");
            button.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    getFragmentManager().beginTransaction().replace(android.R.id.content, new Fragment2()).addToBackStack(null).commit();
                }
            });

            layout.addView(button);

            return layout;
        }
    }

    public static class Fragment2 extends Fragment {

        public Fragment2() {
            setRetainInstance(true);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return new View(inflater.getContext());
        }
    }
}

因此,我已经完成了手动实现保存/恢复逻辑。 缺点是我无法关闭已经存在的save\restore,因此在视图上会调用onSaveInstance/onRestoreInstance两次。除非有一次它本身没有被调用,然后它被调用一次B-

要使其工作,只需添加到Fragment1类:

    SparseArray<Parcelable> savedState;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        if (savedState != null)
            view.restoreHierarchyState(savedState);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        savedState = new SparseArray<Parcelable>();
        getView().saveHierarchyState(savedState);
    }