最近在做项目时,发现Fragment在被replace后再返回(在已经addToBackStack的情况下),原来的Fragment视图变成一片空白。
测试:
Fragment一共有11个生命周期,我把Fragment的生命周期过程全都打一遍Log
public class fragment1 extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.aaaa, container, false); Log.d("fragmentLife", "onCreateView"); return view;}@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("fragmentLife", "onCreate");}@Overridepublic void onAttach(Activity activity) { Log.d("fragmentLife", "onAttach"); super.onAttach(activity);}@Overridepublic void onActivityCreated(Bundle savedInstanceState) { Log.d("fragmentLife", "onActivityCreated"); super.onActivityCreated(savedInstanceState);}@Overridepublic void onStart() { Log.d("fragmentLife", "onStart"); super.onStart();}@Overridepublic void onResume() { Log.d("fragmentLife", "onResume"); super.onResume();}@Overridepublic void onPause() { Log.d("fragmentLife", "onPause"); super.onPause();}@Overridepublic void onStop() { Log.d("fragmentLife", "onStop"); super.onStop();}@Overridepublic void onDestroy() { Log.d("fragmentLife", "onDestroy"); super.onDestroy();} @Override public void onDestroyView() { Log.d("fragmentLife", "onDestroyView"); super.onDestroyView();}@Overridepublic void onDetach() { Log.d("fragmentLife", "onDetach"); super.onDetach();}}然后在Activity中先add再replace,然后再返回,最后退出
int i = 0;@OverridePRotected 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(); }});}@Overridepublic void onBackPressed() { i++;if(i==1){ Log.d("fragmentLife", "返回");}else{ Log.d("fragmentLife", "退出程序"); } super.onBackPressed();}我们来看一下Log日志
D/fragmentLife(2440): 添加D/fragmentLife(2440): onAttachD/fragmentLife(2440): onCreateD/fragmentLife(2440): onCreateViewD/fragmentLife(2440): onActivityCreatedD/fragmentLife(2440): onStartD/fragmentLife(2440): onResumeD/fragmentLife(2440): 替换D/fragmentLife(2440): onPauseD/fragmentLife(2440): onStopD/fragmentLife(2440): onDestroyViewD/fragmentLife(2440): 返回D/fragmentLife(2440): onCreateViewD/fragmentLife(2440): onActivityCreatedD/fragmentLife(2440): onStartD/fragmentLife(2440): onResumeD/fragmentLife(2440): 退出程序D/fragmentLife(2440): onPauseD/fragmentLife(2440): onStopD/fragmentLife(2440): onDestroyViewD/fragmentLife(2440): onDestroyD/fragmentLife(2440): onDetach看出问题: Fragment已经addToBackStack,在被replace后,虽然Fragment实例没有被摧毁,但是会回调onDestroyView()方法,导致视图被摧毁。
解决方法: 定义一个boolean变量,在onCreateView方法中判断此boolean的值,决定是否恢复视图。
1.定义一个boolean变量
private boolean isViewDetroy;2.在onCreate方法中初始化isViewDetroy = false;
@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); returView = false;}3.在Fragment的onDestroyView方法中让isViewDetroy = true;
@Overridepublic void onDestroyView() { super.onDestroyView(); isViewDetroy = true;}4.在onCreatView方法中判断isViewDetroy,如果为true,则恢复视图
@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragmen,container,false); if(isViewDetroy = true){ ...... //此处执行恢复视图操作 } return view;}谢谢!
新闻热点
疑难解答