Fragment回退栈管理
来源:互联网 发布:充值系统源码 编辑:程序博客网 时间:2024/06/05 06:15
一般操作一个fragment是使用fragmentTransaction,fragmentTransaction由fragmentManager获取。
manager = getSupportFragmentManager();FragmentTransaction transaction = manager.beginTransaction();
实际上manager是个FragmentManagerImpl对象,而beginTransaction返回的是一个BackStackRecord具体对象
@Override public FragmentTransaction beginTransaction() { return new BackStackRecord(this); }
FragmentTransaction有多个方法,add,remove,replace(实际上是remove和add的结合),hide,show,detach,attach,addToBackStack。。。
最后都会调用commit来完成一系列动作的提交。
transaction.add()会执行生命周期:
06-29 18:43:47.332 9099-9099/com.txt.mydemo I/OneFragment: onAttach06-29 18:43:47.332 9099-9099/com.txt.mydemo I/OneFragment: onCreate06-29 18:43:47.332 9099-9099/com.txt.mydemo I/OneFragment: onCreateView06-29 18:43:47.340 9099-9099/com.txt.mydemo I/OneFragment: onViewCreated06-29 18:43:47.340 9099-9099/com.txt.mydemo I/OneFragment: onActivityCreated06-29 18:43:47.340 9099-9099/com.txt.mydemo I/OneFragment: onStart06-29 18:43:47.340 9099-9099/com.txt.mydemo I/OneFragment: onResume
transaction.remove会执行生命周期:
06-29 18:45:30.699 9099-9099/com.txt.mydemo I/OneFragment: onPause06-29 18:45:30.699 9099-9099/com.txt.mydemo I/OneFragment: onStop06-29 18:45:30.699 9099-9099/com.txt.mydemo I/OneFragment: onDestroyView06-29 18:45:30.942 9099-9099/com.txt.mydemo I/OneFragment: onDestroy06-29 18:45:30.942 9099-9099/com.txt.mydemo I/OneFragment: onDetach
而使用hide、show则不会执行生命周期,其实就类似于view的setvisible设置可见性
如下这个示例:
public class FragmentActivity extends AppCompatActivity implements OneFragment.OnFragmentInteractionListener{ private FragmentManager manager; private static final String TAG1 = "TAG1", TAG2 = "TAG2";// private FragmentTransaction transaction;//只能作为局部变量,一次只能执行一个fragment的commit; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_test); manager = getSupportFragmentManager(); } public void tab1(View view){ Fragment fragment = manager.findFragmentByTag(TAG1); FragmentTransaction transaction = manager.beginTransaction(); //设置动画效果,必须在add ,replace,remove之前调用 //使用系统默认的动画 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); //使用自定义的动画 transaction.setCustomAnimations(R.anim.slide_in_from_right,R.anim.slide_in_from_right); if(manager.findFragmentByTag(TAG2) != null){ transaction.hide(manager.findFragmentByTag(TAG2)); } if( fragment != null ){ transaction.show(fragment); }else { transaction.add(R.id.content, OneFragment.newInstance("1", "2"), TAG1);// transaction.addToBackStack(null);//添加到回退栈中,在这里只是记录一个标记,其实是在commit中,调用fragmentManager的allocBackStackIndex方法,所以回退栈是由fragmentManager管理的。必须在commit之前 } transaction.commit(); } public void tab2(View view){ Fragment fragment = manager.findFragmentByTag(TAG2); FragmentTransaction transaction = manager.beginTransaction(); if (manager.findFragmentByTag(TAG1) != null) { transaction.hide(manager.findFragmentByTag(TAG1)); } if( fragment != null ) { transaction.show(fragment); }else { transaction.add(R.id.content, TwoFragment.newInstance("abc"), TAG2);// transaction.addToBackStack(null); } transaction.commit(); } //activity向fragment传值 private void setTextToFragment(){ ((OneFragment)manager.findFragmentByTag("tab1")).setTextByActivity(); } //实现tab1的回调接口(即fragment向activity传值) @Override public void onFragmentInteraction(Uri uri) { }}
使用hide和show来切换连个fragment,并且添加fragment的时候不加入回退栈,那么在activity中按back键的时候,两个fragment的生命周期是这样的:
06-29 18:55:34.996 25403-25403/com.txt.mydemo I/OneFragment: onPause06-29 18:55:34.996 25403-25403/com.txt.mydemo I/TwoFragment: onPause06-29 18:55:35.106 25403-25403/com.txt.mydemo W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (2560x1440, max=2048x2048)06-29 18:55:35.496 25403-25403/com.txt.mydemo I/OneFragment: onStop06-29 18:55:35.496 25403-25403/com.txt.mydemo I/TwoFragment: onStop06-29 18:55:35.496 25403-25403/com.txt.mydemo I/OneFragment: onDestroyView06-29 18:55:35.504 25403-25403/com.txt.mydemo I/OneFragment: onDestroy06-29 18:55:35.504 25403-25403/com.txt.mydemo I/OneFragment: onDetach06-29 18:55:35.504 25403-25403/com.txt.mydemo I/TwoFragment: onDestroyView06-29 18:55:35.504 25403-25403/com.txt.mydemo I/TwoFragment: onDestroy06-29 18:55:35.504 25403-25403/com.txt.mydemo I/TwoFragment: onDetach一起结束。
把addToBackStack的注释去掉,则根据添加的先后顺序,依次销毁fragment,不管中间切换过几次hide或show
比如先添加tab2,在添加tab1,back键销毁的是这样的:
06-29 19:07:22.567 30394-30394/com.txt.mydemo I/OneFragment: onPause06-29 19:07:22.567 30394-30394/com.txt.mydemo I/OneFragment: onStop06-29 19:07:22.567 30394-30394/com.txt.mydemo I/OneFragment: onDestroyView06-29 19:07:22.824 30394-30394/com.txt.mydemo I/OneFragment: onDestroy06-29 19:07:22.824 30394-30394/com.txt.mydemo I/OneFragment: onDetach --------- beginning of /dev/log/system06-29 19:07:24.824 30394-30394/com.txt.mydemo I/TwoFragment: onPause06-29 19:07:24.824 30394-30394/com.txt.mydemo I/TwoFragment: onStop06-29 19:07:24.824 30394-30394/com.txt.mydemo I/TwoFragment: onDestroyView06-29 19:07:24.824 30394-30394/com.txt.mydemo I/TwoFragment: onDestroy06-29 19:07:24.832 30394-30394/com.txt.mydemo I/TwoFragment: onDetach
先销毁了后加入的oneFragment。
接着看下replace时的生命周期,先点击tab1按钮,添加oneFragment到界面上,然后点击replaceTab1按钮,添加twoFragment到界面上。在操作这两步的时候,把addTOBackStack方法注释掉,看下效果:
增加了replaceTab1方法
public class FragmentActivity extends AppCompatActivity implements OneFragment.OnFragmentInteractionListener{ private FragmentManager manager; private static final String TAG1 = "TAG1", TAG2 = "TAG2";// private FragmentTransaction transaction;//只能作为局部变量,一次只能执行一个fragment的commit; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_test); manager = getSupportFragmentManager(); } public void tab1(View view){// Fragment fragment = manager.findFragmentByTag(TAG1); FragmentTransaction transaction = manager.beginTransaction(); //设置动画效果,必须在add ,replace,remove之前调用 //使用系统默认的动画 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); //使用自定义的动画 transaction.setCustomAnimations(R.anim.slide_in_from_right,R.anim.slide_in_from_right);// if(manager.findFragmentByTag(TAG2) != null){// transaction.hide(manager.findFragmentByTag(TAG2));// }// if( fragment != null ){// transaction.show(fragment);// }else { transaction.add(R.id.content, OneFragment.newInstance("1", "2"), TAG1);// transaction.addToBackStack(null);//添加到回退栈中,在这里只是记录一个标记,其实是在commit中,调用fragmentManager的allocBackStackIndex方法,所以回退栈是由fragmentManager管理的。必须在commit之前// } transaction.commit(); } public void tab2(View view){ Fragment fragment = manager.findFragmentByTag(TAG2); FragmentTransaction transaction = manager.beginTransaction(); if (manager.findFragmentByTag(TAG1) != null) { transaction.hide(manager.findFragmentByTag(TAG1)); } if( fragment != null ) { transaction.show(fragment); }else { transaction.add(R.id.content, TwoFragment.newInstance("abc"), TAG2); transaction.addToBackStack(null); } transaction.commit(); } public void replaceTab1(View view){ FragmentTransaction transaction = manager.beginTransaction(); transaction.replace(R.id.content, TwoFragment.newInstance("abc"), TAG2);// transaction.addToBackStack(null); transaction.commit(); } //activity向fragment传值 private void setTextToFragment(){ ((OneFragment)manager.findFragmentByTag("tab1")).setTextByActivity(); } //实现tab1的回调接口(即fragment向activity传值) @Override public void onFragmentInteraction(Uri uri) { }}
1、把addToBackStack都注释掉
添加onefragment
06-29 19:38:59.629 30449-30449/com.txt.mydemo I/OneFragment: onAttach06-29 19:38:59.629 30449-30449/com.txt.mydemo I/OneFragment: onCreate06-29 19:38:59.629 30449-30449/com.txt.mydemo I/OneFragment: onCreateView06-29 19:38:59.645 30449-30449/com.txt.mydemo I/OneFragment: onViewCreated06-29 19:38:59.645 30449-30449/com.txt.mydemo I/OneFragment: onActivityCreated06-29 19:38:59.645 30449-30449/com.txt.mydemo I/OneFragment: onStart06-29 19:38:59.645 30449-30449/com.txt.mydemo I/OneFragment: onResume
使用replace把twofragment添加上去,很明显,没有把任何fragment加入回退栈,那么很明显,onefragment此时要被销毁了。
06-29 19:39:48.488 30449-30449/com.txt.mydemo I/OneFragment: onPause06-29 19:39:48.488 30449-30449/com.txt.mydemo I/OneFragment: onStop06-29 19:39:48.488 30449-30449/com.txt.mydemo I/OneFragment: onDestroyView06-29 19:39:48.488 30449-30449/com.txt.mydemo I/OneFragment: onDestroy06-29 19:39:48.488 30449-30449/com.txt.mydemo I/OneFragment: onDetach06-29 19:39:48.488 30449-30449/com.txt.mydemo I/TwoFragment: onAttach06-29 19:39:48.488 30449-30449/com.txt.mydemo I/TwoFragment: onCreate06-29 19:39:48.488 30449-30449/com.txt.mydemo I/TwoFragment: onCreateView06-29 19:39:48.504 30449-30449/com.txt.mydemo I/TwoFragment: onViewCreated06-29 19:39:48.504 30449-30449/com.txt.mydemo I/TwoFragment: onActivityCreated06-29 19:39:48.504 30449-30449/com.txt.mydemo I/TwoFragment: onStart06-29 19:39:48.504 30449-30449/com.txt.mydemo I/TwoFragment: onResume
06-29 19:40:14.559 30449-30449/com.txt.mydemo I/TwoFragment: onPause06-29 19:40:14.676 30449-30449/com.txt.mydemo W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (2560x1440, max=2048x2048)06-29 19:40:15.035 30449-30449/com.txt.mydemo I/TwoFragment: onStop06-29 19:40:15.035 30449-30449/com.txt.mydemo I/TwoFragment: onDestroyView06-29 19:40:15.035 30449-30449/com.txt.mydemo I/TwoFragment: onDestroy06-29 19:40:15.035 30449-30449/com.txt.mydemo I/TwoFragment: onDetach
06-29 19:49:31.160 5569-5569/com.txt.mydemo I/OneFragment: onAttach06-29 19:49:31.160 5569-5569/com.txt.mydemo I/OneFragment: onCreate06-29 19:49:31.160 5569-5569/com.txt.mydemo I/OneFragment: onCreateView06-29 19:49:31.176 5569-5569/com.txt.mydemo I/OneFragment: onViewCreated06-29 19:49:31.176 5569-5569/com.txt.mydemo I/OneFragment: onActivityCreated06-29 19:49:31.176 5569-5569/com.txt.mydemo I/OneFragment: onStart06-29 19:49:31.176 5569-5569/com.txt.mydemo I/OneFragment: onResume
06-29 19:49:57.863 5569-5569/com.txt.mydemo I/OneFragment: onPause06-29 19:49:57.863 5569-5569/com.txt.mydemo I/OneFragment: onStop06-29 19:49:57.863 5569-5569/com.txt.mydemo I/OneFragment: onDestroyView06-29 19:49:57.863 5569-5569/com.txt.mydemo I/TwoFragment: onAttach06-29 19:49:57.863 5569-5569/com.txt.mydemo I/TwoFragment: onCreate06-29 19:49:57.863 5569-5569/com.txt.mydemo I/TwoFragment: onCreateView06-29 19:49:57.879 5569-5569/com.txt.mydemo I/TwoFragment: onViewCreated06-29 19:49:57.879 5569-5569/com.txt.mydemo I/TwoFragment: onActivityCreated06-29 19:49:57.879 5569-5569/com.txt.mydemo I/TwoFragment: onStart06-29 19:49:57.879 5569-5569/com.txt.mydemo I/TwoFragment: onResume
06-29 19:50:35.942 5569-5569/com.txt.mydemo I/OneFragment: onDestroy06-29 19:50:35.942 5569-5569/com.txt.mydemo I/OneFragment: onDetach
06-29 20:05:45.520 18607-18607/com.txt.mydemo I/OneFragment: onAttach06-29 20:05:45.520 18607-18607/com.txt.mydemo I/OneFragment: onCreate06-29 20:05:45.527 18607-18607/com.txt.mydemo I/OneFragment: onCreateView06-29 20:05:45.535 18607-18607/com.txt.mydemo I/OneFragment: onViewCreated06-29 20:05:45.535 18607-18607/com.txt.mydemo I/OneFragment: onActivityCreated06-29 20:05:45.535 18607-18607/com.txt.mydemo I/OneFragment: onStart06-29 20:05:45.535 18607-18607/com.txt.mydemo I/OneFragment: onResume
06-29 20:06:15.512 18607-18607/com.txt.mydemo I/OneFragment: onPause06-29 20:06:15.512 18607-18607/com.txt.mydemo I/OneFragment: onStop06-29 20:06:15.512 18607-18607/com.txt.mydemo I/OneFragment: onDestroyView06-29 20:06:15.512 18607-18607/com.txt.mydemo I/TwoFragment: onAttach06-29 20:06:15.512 18607-18607/com.txt.mydemo I/TwoFragment: onCreate06-29 20:06:15.512 18607-18607/com.txt.mydemo I/TwoFragment: onCreateView06-29 20:06:15.527 18607-18607/com.txt.mydemo I/TwoFragment: onViewCreated06-29 20:06:15.527 18607-18607/com.txt.mydemo I/TwoFragment: onActivityCreated06-29 20:06:15.527 18607-18607/com.txt.mydemo I/TwoFragment: onStart06-29 20:06:15.527 18607-18607/com.txt.mydemo I/TwoFragment: onResume
06-29 20:07:34.090 18607-18607/com.txt.mydemo I/TwoFragment: onPause06-29 20:07:34.090 18607-18607/com.txt.mydemo I/TwoFragment: onStop06-29 20:07:34.090 18607-18607/com.txt.mydemo I/TwoFragment: onDestroyView06-29 20:07:34.090 18607-18607/com.txt.mydemo I/TwoFragment: onDestroy06-29 20:07:34.090 18607-18607/com.txt.mydemo I/TwoFragment: onDetach06-29 20:07:34.090 18607-18607/com.txt.mydemo I/OneFragment: onCreateView06-29 20:07:34.098 18607-18607/com.txt.mydemo I/OneFragment: onViewCreated06-29 20:07:34.098 18607-18607/com.txt.mydemo I/OneFragment: onActivityCreated06-29 20:07:34.098 18607-18607/com.txt.mydemo I/OneFragment: onStart06-29 20:07:34.098 18607-18607/com.txt.mydemo I/OneFragment: onResume
06-29 20:08:57.488 18607-18607/com.txt.mydemo I/OneFragment: onPause06-29 20:08:57.598 18607-18607/com.txt.mydemo W/OpenGLRenderer: Bitmap too large to be uploaded into a texture (2560x1440, max=2048x2048)06-29 20:08:58.027 18607-18607/com.txt.mydemo I/OneFragment: onStop06-29 20:08:58.027 18607-18607/com.txt.mydemo I/OneFragment: onDestroyView06-29 20:08:58.035 18607-18607/com.txt.mydemo I/OneFragment: onDestroy06-29 20:08:58.035 18607-18607/com.txt.mydemo I/OneFragment: onDetach
4、再来看下,把tab1方法中的addToBackStack加上,也就是把oneFragment也加入回退栈中
06-29 20:17:58.027 30768-30768/com.txt.mydemo I/OneFragment: onAttach06-29 20:17:58.027 30768-30768/com.txt.mydemo I/OneFragment: onCreate06-29 20:17:58.027 30768-30768/com.txt.mydemo I/OneFragment: onCreateView06-29 20:17:58.035 30768-30768/com.txt.mydemo I/OneFragment: onViewCreated06-29 20:17:58.035 30768-30768/com.txt.mydemo I/OneFragment: onActivityCreated06-29 20:17:58.035 30768-30768/com.txt.mydemo I/OneFragment: onStart06-29 20:17:58.035 30768-30768/com.txt.mydemo I/OneFragment: onResume
06-29 20:18:30.387 30768-30768/com.txt.mydemo I/OneFragment: onPause06-29 20:18:30.387 30768-30768/com.txt.mydemo I/OneFragment: onStop06-29 20:18:30.387 30768-30768/com.txt.mydemo I/OneFragment: onDestroyView06-29 20:18:30.387 30768-30768/com.txt.mydemo I/TwoFragment: onAttach06-29 20:18:30.387 30768-30768/com.txt.mydemo I/TwoFragment: onCreate06-29 20:18:30.387 30768-30768/com.txt.mydemo I/TwoFragment: onCreateView06-29 20:18:30.395 30768-30768/com.txt.mydemo I/TwoFragment: onViewCreated06-29 20:18:30.395 30768-30768/com.txt.mydemo I/TwoFragment: onActivityCreated06-29 20:18:30.395 30768-30768/com.txt.mydemo I/TwoFragment: onStart06-29 20:18:30.395 30768-30768/com.txt.mydemo I/TwoFragment: onResume
06-29 20:20:07.746 30768-30768/com.txt.mydemo I/TwoFragment: onPause06-29 20:20:07.746 30768-30768/com.txt.mydemo I/TwoFragment: onStop06-29 20:20:07.746 30768-30768/com.txt.mydemo I/TwoFragment: onDestroyView06-29 20:20:07.746 30768-30768/com.txt.mydemo I/TwoFragment: onDestroy06-29 20:20:07.746 30768-30768/com.txt.mydemo I/TwoFragment: onDetach06-29 20:20:07.746 30768-30768/com.txt.mydemo I/OneFragment: onCreateView06-29 20:20:07.762 30768-30768/com.txt.mydemo I/OneFragment: onViewCreated06-29 20:20:07.762 30768-30768/com.txt.mydemo I/OneFragment: onActivityCreated06-29 20:20:07.762 30768-30768/com.txt.mydemo I/OneFragment: onStart06-29 20:20:07.762 30768-30768/com.txt.mydemo I/OneFragment: onResume
06-29 20:26:34.926 30768-30768/com.txt.mydemo I/OneFragment: onPause06-29 20:26:34.926 30768-30768/com.txt.mydemo I/OneFragment: onStop06-29 20:26:34.926 30768-30768/com.txt.mydemo I/OneFragment: onDestroyView06-29 20:26:35.176 30768-30768/com.txt.mydemo I/OneFragment: onDestroy06-29 20:26:35.176 30768-30768/com.txt.mydemo I/OneFragment: onDetach
addToBackStack的源码分析
另外从源码中可以看出,addToBackStack方法只是为当前的fragmentTransaction设置了一个标记,真正执行入栈的还是在调用了commit后,由fragmentManager来执行,
BackStackRecord中的设置标记mAddToBackStack为true:
public FragmentTransaction addToBackStack(String name) { if (!mAllowAddToBackStack) { throw new IllegalStateException( "This FragmentTransaction is not allowed to be added to the back stack."); } mAddToBackStack = true; mName = name; return this; }
commit方法:
@Override public int commit() { return commitInternal(false); }
int commitInternal(boolean allowStateLoss) { if (mCommitted) throw new IllegalStateException("commit already called"); if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "Commit: " + this); LogWriter logw = new LogWriter(TAG); PrintWriter pw = new PrintWriter(logw); dump(" ", null, pw, null); pw.close(); } mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); } else { mIndex = -1; } mManager.enqueueAction(this, allowStateLoss); return mIndex; }调用了manager的allocBackStackIndex方法来入栈。
具体细节参考:简析 addToBackStack使用和Fragment执行流程
- Fragment回退栈管理
- Fragment回退栈管理
- Fragment的回退栈管理分析
- (5)Fragment回退栈的管理
- Android Fragment---管理Fragment
- Android Fragment---管理Fragment
- 管理fragment
- Fragment管理
- fragment管理
- fragment 管理
- Fragment管理
- 管理fragment
- Fragment学习之回退栈的管理
- 对于activity与fragment回退栈的管理
- viewpager+fragment 如何管理fragment
- viewpager+fragment 如何管理fragment
- fragment嵌套fragment的管理
- 8 管理fragment生命周期
- des 3des aes ides rsa 对称加密算法
- MPEG4与.mp4
- 守护进程(Daemon)
- vim如何删除文件中所有东西
- SimpleDateFormat.format的简单使用小结
- Fragment回退栈管理
- 关于 bash:$'\r': command not found 的问题
- 个人博客的搭建
- ViewStub
- SSD5 数据结构 Course Design Exercise 3 解析
- 那么来一波模板吧=。=
- git添加到idea中流程
- Spring Boot系列教程七:Spring boot集成MyBatis
- css3 实现选项卡小三角形状