在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; }
谢谢!