片段setRetainInstance(true)时不调用View.onRestoreInstanceState(片段在后栈中时双屏方向改变)

时间:2014-06-09 14:05:12

标签: android android-fragments android-view

我有两个片段:一个在另一个片段之上。片段在其构造函数中有setRetainInstance(true)

当我进行双屏翻转并按后退键时,顶部片段会弹出并且底部片段变得可见。但是底部片段的视图不会收到onRestoreInstanceState

当我删除setRetainInstance(true)时,一切正常。但我需要setRetainInstance(true)使用多个线程,所以我无法解决我的问题那么简单。 :)

如何保证在这种情况下调用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());
        }
    }
}

1 个答案:

答案 0 :(得分:0)

所以,我已经手动完成了保存/恢复逻辑。 减号是我无法关闭已存在的save \ restore,因此在View上调用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);
    }