Fragment被replace后视图被摧毁

在Fragment被replace后再返回,视图变成了空白

最近在做项目时,发现Fragment在被replace后再返回(在已经addToBackStack的情况下),原来的Fragment视图变成一片空白。

测试:

  • Fragment一共有11个生命周期,我把Fragment的生命周期过程全都打一遍Log

    public class fragment1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.aaaa, container, false);
      Log.d("fragmentLife", "onCreateView");
        return view;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      Log.d("fragmentLife", "onCreate");
    }
    
    @Override
    public void onAttach(Activity activity) {
      Log.d("fragmentLife", "onAttach");
      super.onAttach(activity);
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
      Log.d("fragmentLife", "onActivityCreated");
      super.onActivityCreated(savedInstanceState);
    }
    
    @Override
    public void onStart() {
      Log.d("fragmentLife", "onStart");
      super.onStart();
    }
    
    @Override
    public void onResume() {
      Log.d("fragmentLife", "onResume");
      super.onResume();
    }
    
    @Override
    public void onPause() {
      Log.d("fragmentLife", "onPause");
      super.onPause();
    }
    
    @Override
    public void onStop() {
      Log.d("fragmentLife", "onStop");
      super.onStop();
    }
    
    @Override
    public void onDestroy() {
      Log.d("fragmentLife", "onDestroy");
      super.onDestroy();
    }
    
      @Override
      public void onDestroyView() {
      Log.d("fragmentLife", "onDestroyView");
      super.onDestroyView();
    }
    
    @Override
    public void onDetach() {
      Log.d("fragmentLife", "onDetach");
      super.onDetach();
    }
    } 
    
  • 然后在Activity中先add再replace,然后再返回,最后退出

    int i = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
    
      Log.d("fragmentLife", "添加");
      getFragmentManager().beginTransaction()
      .add(R.id.container, new fragment1())
      .commit();
    
      Button button = (Button)findViewById(R.id.button1);
      button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("fragmentLife", "替换");
            getFragmentManager().beginTransaction()
            .replace(R.id.container, new fragment2())
            .addToBackStack(null)
            .commit();  
        }
    });
    }
    
    @Override
    public void onBackPressed() {
        i++;
    if(i==1){
        Log.d("fragmentLife", "返回");
    }else{
      Log.d("fragmentLife", "退出程序");
        }
      super.onBackPressed();
    }
    
  • 我们来看一下Log日志

    D/fragmentLife(2440): 添加
    D/fragmentLife(2440): onAttach
    D/fragmentLife(2440): onCreate
    D/fragmentLife(2440): onCreateView
    D/fragmentLife(2440): onActivityCreated
    D/fragmentLife(2440): onStart
    D/fragmentLife(2440): onResume
    D/fragmentLife(2440): 替换
    D/fragmentLife(2440): onPause
    D/fragmentLife(2440): onStop
    D/fragmentLife(2440): onDestroyView
    D/fragmentLife(2440): 返回
    D/fragmentLife(2440): onCreateView
    D/fragmentLife(2440): onActivityCreated
    D/fragmentLife(2440): onStart
    D/fragmentLife(2440): onResume
    D/fragmentLife(2440): 退出程序
    D/fragmentLife(2440): onPause
    D/fragmentLife(2440): onStop
    D/fragmentLife(2440): onDestroyView
    D/fragmentLife(2440): onDestroy
    D/fragmentLife(2440): onDetach
    

看出问题: Fragment已经addToBackStack,在被replace后,虽然Fragment实例没有被摧毁,但是会回调onDestroyView()方法,导致视图被摧毁。

解决方法: 定义一个boolean变量,在onCreateView方法中判断此boolean的值,决定是否恢复视图。

  • 1.定义一个boolean变量

    private boolean isViewDetroy;
    
  • 2.在onCreate方法中初始化isViewDetroy = false;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        returView = false;
    }
    
  • 3.在Fragment的onDestroyView方法中让isViewDetroy = true;

    @Override
    public void onDestroyView() {
       super.onDestroyView();
       isViewDetroy = true;
    }
    
  • 4.在onCreatView方法中判断isViewDetroy,如果为true,则恢复视图

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragmen,container,false);
    
       if(isViewDetroy = true){
           ......  //此处执行恢复视图操作
        }
        return view;
    }
    

谢谢!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章