静态引入Fragment :
- 书写一个Fragment 类,重新
onCreateView
方法 ,inflate
Fragment 的布局
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, container, false);
return view;
}
- 在Activity 布局标签中引入Fragment ,其中
name
属性为刚刚创建的Fragment 类全路径
<fragment
android:id="@+id/gragment1"
android:layout_width="match_parent"
android:name="com.mavolas.activitydemo.fragment.TitleFragment"
android:layout_height="50dp">
</fragment>
动态引入Fragment
(因为app 包下的Fragment 已经过时了, 我们创建Fragment 时候引用v4 包下面的)
Activity继承 AppCompatActivity 或者 FragmentActivity
//获取FragmentManager
FragmentManager fm = getSupportFragmentManager();
//开启事务
FragmentTransaction trans = fm.beginTransaction();
//添加fragment
trans.add(R.id.ll1,new TitleFragment());
//添加fragment
trans.add(R.id.ll2, new ContentFragment());
//提交事务
trans.commit();
生命周期方法:
情况1
Activity 当中默认加载一个 Fragment
//进入app,add 方法添加Fragment
Activity1_onCreate()→
Fragment1_onAttach()→Fragment1_onCreate()→Fragment1_onCreateView()→Fragment1_onViewCreated()→Fragment1_onActivityCreated()→Fragment1_onViewStateRestored()→onStart()→
Activity1_onStart()→ Activity1_onPostCreate()→ Activity1_onResume()→
Fragment1_onResume()→
Activity1_onPostResume()
//remove 方法
Fragment1_onPause()→Fragment1_onStop()→Fragment1_onDestroyView()→Fragment1_onDestroy()→Fragment1_onDetach()→
//detach 方法
Fragment1_onPause()→Fragment1_onStop()→Fragment1_onDestroyView()
//detach 之后再 attach
Fragment1_onCreateView()→Fragment1_onViewCreated()→Fragment1_onActivityCreated()→Fragment1_onViewStateRestored()→Fragment1_onStart()→Fragment1_onResume()→
//按 home 键 或者任务菜单键 返回
Fragment1_onPause()→
Activity1_onPause()→
Fragment1_onSaveInstanceState()→
Activity1_onSaveInstanceState()→
Fragment1_onStop()→
Activity1_onStop()
//home 键返回后恢复
Activity1_onRestart()→
Fragment1_onStart()→
Activity1_onStart()→ Activity1_onResume()→
Fragment1_onResume()→
Activity1_onPostResume()
//按返回键退出:
Fragment1_onPause()→
Activity1_onPause()→
Fragment1_onStop()→
Activity1_onStop()→
Fragment1_onDestroyView()→
Fragment1_onDestroy()→
Fragment1_onDetach()→
Activity1_onDestroy()→
情况2
两个Fragment 通过replace 切换:Fragment1 切换到Fragment2
Fragment2_onAttach()→Fragment2_onCreate()→
Fragment1_onPause()→Fragment1_onStop()→Fragment1_onDestroyView()→Fragment1_onDestroy()→Fragment1_onDetach()→
Fragment2_onCreateView()→Fragment2_onViewCreated()→Fragment2_onActivityCreated()→Fragment2_onViewStateRestored()→Fragment2_onStart()→Fragment2_onResume()
replace 相当于remove 和 add 的结合体
情况3
Fragment 通过hide 和 show 显示和隐藏Fragment:
不会调用任何生命周期方法
情况4
DialogFragment 在Activity 中弹出Dialog,Dialog 有正常的启动生命周期方法。
//正常打开dialog
DialogFragment_onAttach()→DialogFragment_onCreate()→DialogFragment_onCreateDialog()→DialogFragment_onCreateView()→
DialogFragment_onActivityCreated()→DialogFragment_onStart()→DialogFragment_onResume()→
//横竖屏切换,dialog 不会消失
DialogFragment_onPause()→DialogFragment_onSaveInstanceState()→DialogFragment_onStop()→DialogFragment_onDestroyView()→
DialogFragment_onDestroy()→DialogFragment_onDetach()→DialogFragment_onAttach()→DialogFragment_onCreate()→
DialogFragment_onCreateDialog()→DialogFragment_onCreateView()→DialogFragment_onActivityCreated()→DialogFragment_onStart()→DialogFragment_onResume()
情况5
DialogFragment 和一般Fragment 设置 setRetainInstance(true)
的情况:
//当在 onCreate 里面设置 setRetainInstance(true); 横竖屏切换,可以看到恢复时 恢复时跳过了onDestroy()和onCreate(),但是恢复之后即被销毁。
DialogFragment_onPause()→DialogFragment_onSaveInstanceState()→DialogFragment_onStop()→DialogFragment_onDestroyView()→
DialogFragment_onDetach()→DialogFragment_onAttach()→DialogFragment_onCreateDialog()→DialogFragment_onCreateView()→DialogFragment_onActivityCreated()→DialogFragment_onStart()→DialogFragment_onResume()→
DialogFragment_onPause()→DialogFragment_onStop()→DialogFragment_onDestroyView()→DialogFragment_onDestroy()→DialogFragment_onDetach()
//如果设置 setRetainInstance(true); 不是 Dialog 的情况:可以发现由于没有Destroy 会连续多次调用OnStart OnResume
Fragment1_onPause()→Fragment1_onSaveInstanceState()→Fragment1_onStop()→Fragment1_onDestroyView()→Fragment1_onDetach()→
Fragment1_onAttach()→Fragment1_onCreateView()→Fragment1_onViewCreated()→Fragment1_onActivityCreated()→Fragment1_onViewStateRestored()→
Fragment1_onAttach()→Fragment1_onCreate()→Fragment1_onCreateView()→Fragment1_onViewCreated()→Fragment1_onActivityCreated()→Fragment1_onViewStateRestored()→
Fragment1_onStart()→Fragment1_onStart()→
Fragment1_onResume()→Fragment1_onResume()
//如果反复横竖屏切换 先切换到横屏,再切换到竖屏, 可以看到生命周期方法多次被调用:
Fragment1_onPause()→Fragment1_onPause()→
Fragment1_onSaveInstanceState()→Fragment1_onSaveInstanceState()→
Fragment1_onStop()→Fragment1_onStop()→
Fragment1_onDestroyView()→Fragment1_onDetach()→
Fragment1_onDestroyView()→Fragment1_onDetach()→
Fragment1_onAttach()→Fragment1_onAttach()→
Fragment1_onCreateView()→Fragment1_onViewCreated()→Fragment1_onActivityCreated()→Fragment1_onViewStateRestored()→
Fragment1_onCreateView()→Fragment1_onViewCreated()→Fragment1_onActivityCreated()→Fragment1_onViewStateRestored()→
Fragment1_onAttach()→Fragment1_onCreate()→Fragment1_onCreateView()→Fragment1_onViewCreated()→Fragment1_onActivityCreated()→Fragment1_onViewStateRestored()→
Fragment1_onStart()→Fragment1_onStart()→Fragment1_onStart()→
Fragment1_onResume()→Fragment1_onResume()→Fragment1_onResume()
总结:
Frament 中 onSaveInstanceState(Bundle outState) 调用的时机
- 列表内容 home键最小化时,在onPause后调用 长
- 按home键,在onPause后调用 按下电源键,在onPause后调用
- 托管该Fragment的Activity 旋转时,在onPause后调用
- 托管该Fragment的Activity开启新的Activity时,在onPause后调用 补充:即使该Fragment在回退栈中,当前展示的不是它,上面几种情况也是成立的
- 补充:此方法被调用时,如果向outState里添加了key-value对,那么在和onCreate(Bundle savedInstanceState)和onViewCreated(View view, @Nullable Bundle savedInstanceState)中拿到的bundle中会有存入的key-value对
Fragment 中 setRetainInstance方法介绍
- Fragment还可以通过setRetainInstance(boolean)来保存自定义的对象数据(Fragment中都有此方法,Activity中无此方法), 当在Fragment的onCreate()方法中调用了setRetainInstance(true)后,Activity被系统销毁又重新创建时(如屏幕旋转),可以不完全销毁Fragment,Fragment中的成员变量值会保留,恢复时跳过了onDestroy()和onCreate()