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