在屏幕旋转时保留片段数据

Retain fragment data on screen rotation

我有 3 个片段,其中 1 个片段更改了另外 2 个片段。

问题是:当我旋转屏幕背景颜色时,片段2和片段3的位置恢复了。 我想保留它们而不修改 AndroidManifest.xml。 最好使用 onSaveInstanceState 或 setRetainInstance 还是两者都使用?

我找到了一些关于保留片段的其他答案,但 none 对我的情况有帮助。

第一个片段

public class FirstFragment extends Fragment 
{
    private OnFragmentInteractionListener mListener;
    private ChangeColorListener mCallBack;
    private boolean clickCheck = false;

    public FirstFragment() { }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_first, container, false);

        Button buttonOk = v.findViewById(R.id.button_ok);
        Button btn = v.findViewById(R.id.button_replace);
        buttonOk.setOnClickListener(v1 -> mCallBack.changeColor(R.color.black));
        btn.setOnClickListener(v12 -> {
            clickCheck = !clickCheck;
            mListener.changeFragment(clickCheck);
        });

        return v;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        
        if (savedInstanceState!=null) {
            mCallBack =(MainActivity)getActivity();
            mListener = (MainActivity)getActivity();
        }
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        if (context instanceof ChangeColorListener) {
            mCallBack = (ChangeColorListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement ChangeColorListener");
        }

        try {
            mListener = (OnFragmentInteractionListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }


    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }
}

第二个片段

public class SecondFragment extends Fragment 
{
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_second, container, false);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }
    public void change(int color){
        getView().setBackgroundColor(color);
    }
}

第三片段

public class ThirdFragment extends Fragment {


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_third, container, false);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);

    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    public void change(int color){
        getView().setBackgroundColor(color);
    }
}

setRetainInstance() is deprecated. ViewModel 建议在配置更改时保留数据。