使用replace时候
- 创建Fragment或者第一次切换到该Fragment,分别执行onAttach()、onCreate()、onCreateView()、onActivityCreated()、onstart()、onResume()方法。
- 锁屏,分别执行onPause()、onStop()方法。
- 亮屏,分别执行onstart()、onResume()方法。
- 覆盖,切换到其他Fragment,分别执行onPause()、onStop()、onDestroyView()方法。
- 从其他Fragment回到之前Fragment,分别执行onCreateView()、onActivityCreated()、onstart()、onResume()方法。
使用hide和show时候
- 创建Fragment或者第一次切换到该Fragment,分别执行onAttach()、onCreate()、onCreateView()、onActivityCreated()、onstart()、onResume()方法。
- 有fragment缓存的时候只调用onHiddenChanged
|
二、回滚操作
最常用:依次回滚
1 2 3 4 5 6 7 8 |
|
拓展:指定回滚
1 |
|
参数string name是transaction.addToBackStack(String tag)
中的tag值;
至于int flags有两个取值:0或FragmentManager.POP_BACK_STACK_INCLUSIVE
;
当取值0时,表示除了参数一指定这一层之上的所有层都退出栈,指定的这一层为栈顶层;
当取值POP_BACK_STACK_INCLUSIVE时,表示连着参数一指定的这一层一起退出栈;
退回栈顶:
1 2 3 |
|
使用ViewPager和Fragment时候
- 创建Fragment或者第一次切换到该Fragment,分别执行onAttach()、onCreate()、onCreateView()、onActivityCreated()、onstart()、onResume()方法。
- 覆盖,setOffscreenPageLimit设置预加载个数
不使用缓存切换到其他Fragment,分别执行setUserVisibleHint false ,onPause()、onStop()、onDestroyView()方法。达到缓存要求的被覆盖调用setUserVisibleHint false - 从其他Fragment回到之前Fragment,不存在缓存分别执行onCreateView()、onActivityCreated()、onstart()、onResume()方法。存在缓存调用setUserVisibleHint true
1,设置预加载个数setOffscreenPageLimit(2)初始化log(总共one,two,three,four四个页面)
- 09-03 16:37:55.769 20098-20098/com.xcm91.relation.myapplication I/OneFragment: setUserVisibleHint false
09-03 16:37:55.769 20098-20098/com.xcm91.relation.myapplication I/TwoFragment: setUserVisibleHint false
09-03 16:37:55.769 20098-20098/com.xcm91.relation.myapplication I/ThreeFragment: setUserVisibleHint false
09-03 16:37:55.769 20098-20098/com.xcm91.relation.myapplication I/OneFragment: setUserVisibleHint true onAttach onCreate
09-03 16:37:55.769 20098-20098/com.xcm91.relation.myapplication I/TwoFragment: onAttach
onCreate
09-03 16:37:55.769 20098-20098/com.xcm91.relation.myapplication I/ThreeFragment: onAttach onCreate
09-03 16:37:55.770 20098-20098/com.xcm91.relation.myapplication I/OneFragment: onCreateView
onActivityCreated
onStart
onResume
09-03 16:37:55.778 20098-20098/com.xcm91.relation.myapplication I/TwoFragment: onActivityCreated
09-03 16:37:55.781 20098-20098/com.xcm91.relation.myapplication I/ThreeFragment: onActivityCreated
09-03 16:37:55.781 20098-20098/com.xcm91.relation.myapplication I/TwoFragment: onStart
onResume
09-03 16:37:55.781 20098-20098/com.xcm91.relation.myapplication I/ThreeFragment: onStart
onResume
2,one切换到two
09-03 16:47:46.978 21114-21114/com.xcm91.relation.myapplication I/FourFragment: setUserVisibleHint false
09-03 16:47:46.979 21114-21114/com.xcm91.relation.myapplication I/OneFragment: setUserVisibleHint false
09-03 16:47:46.979 21114-21114/com.xcm91.relation.myapplication I/TwoFragment: setUserVisibleHint true
09-03 16:47:46.979 21114-21114/com.xcm91.relation.myapplication I/FourFragment: onAttach
onCreate
09-03 16:47:46.987 21114-21114/com.xcm91.relation.myapplication I/FourFragment: onActivityCreated
09-03 16:47:46.988 21114-21114/com.xcm91.relation.myapplication I/FourFragment: onStart
onResume
3,three切换到four
09-03 16:50:54.153 21114-21114/com.xcm91.relation.myapplication I/ThreeFragment: setUserVisibleHint false
09-03 16:50:54.154 21114-21114/com.xcm91.relation.myapplication I/FourFragment: setUserVisibleHint true
09-03 16:50:54.154 21114-21114/com.xcm91.relation.myapplication I/OneFragment: onPause
09-03 16:50:54.155 21114-21114/com.xcm91.relation.myapplication I/OneFragment: onStop
onDestroyView
4,在four的时候待机
09-03 16:53:19.489 21114-21114/com.xcm91.relation.myapplication I/TwoFragment: onPause
09-03 16:53:19.490 21114-21114/com.xcm91.relation.myapplication I/ThreeFragment: onPause
09-03 16:53:19.490 21114-21114/com.xcm91.relation.myapplication I/FourFragment: onPause
09-03 16:53:19.495 21114-21114/com.xcm91.relation.myapplication I/OneFragment: onSaveInstanceStateBundle[{}]
09-03 16:53:19.495 21114-21114/com.xcm91.relation.myapplication I/TwoFragment: onSaveInstanceStateBundle[{}]
09-03 16:53:19.495 21114-21114/com.xcm91.relation.myapplication I/ThreeFragment: onSaveInstanceStateBundle[{}]
09-03 16:53:19.495 21114-21114/com.xcm91.relation.myapplication I/FourFragment: onSaveInstanceStateBundle[{}]
09-03 16:53:19.516 21114-21114/com.xcm91.relation.myapplication I/TwoFragment: onStop
09-03 16:53:19.516 21114-21114/com.xcm91.relation.myapplication I/ThreeFragment: onStop
09-03 16:53:19.516 21114-21114/com.xcm91.relation.myapplication I/FourFragment: onStop
5,one切换到four
09-19 01:49:49.878 9943-9943/com.xcm91.relation.myapplication I/FourFragment: setUserVisibleHintfalse
09-19 01:49:49.878 9943-9943/com.xcm91.relation.myapplication I/OneFragment: setUserVisibleHintfalse
09-19 01:49:49.878 9943-9943/com.xcm91.relation.myapplication I/FourFragment: setUserVisibleHinttrue
09-19 01:49:49.880 9943-9943/com.xcm91.relation.myapplication I/FourFragment: onAttach
onCreate
09-19 01:49:49.955 9943-9943/com.xcm91.relation.myapplication I/FourFragment: AccountPageFragment--lazyLoad
09-19 01:49:49.967 9943-9943/com.xcm91.relation.myapplication I/FourFragment: onActivityCreated
onStart
09-19 01:49:49.968 9943-9943/com.xcm91.relation.myapplication I/FourFragment: onResume
09-19 01:49:49.970 9943-9943/com.xcm91.relation.myapplication I/OneFragment: onPause
onStop
09-19 01:49:49.971 9943-9943/com.xcm91.relation.myapplication I/OneFragment: onDestroyView
去重叠
@Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
/*获取保存的fragment 没有的话返回null*/
mOneFragment = (OneFragment) getSupportFragmentManager().getFragment(savedInstanceState, ONE_FRAGMENT_KEY);
mTwoFragment = (TwoFragment) getSupportFragmentManager().getFragment(savedInstanceState, TWO_FRAGMENT_KEY);
mFragmentThree = (ThreeFragment) getSupportFragmentManager().getFragment(savedInstanceState, THREE_FRAGMENT_KEY);
mFragmentFour = (FourFragment) getSupportFragmentManager().getFragment(savedInstanceState, FOUR_FRAGMENT_KEY);
}
if (mOneFragment == null) mOneFragment = new OneFragment();
if (mTwoFragment == null) mTwoFragment = new TwoFragment();
if (mFragmentThree == null) mFragmentThree = new ThreeFragment();
if (mFragmentFour == null) mFragmentFour = new FourFragment();
mFragmentList.add(mOneFragment);
mFragmentList.add(mTwoFragment);
mFragmentList.add(mFragmentThree);
mFragmentList.add(mFragmentFour);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
/*fragment不为空时 保存*/
if (mOneFragment != null&&mOneFragment .isAdded()) {
getSupportFragmentManager().putFragment(outState, ONE_FRAGMENT_KEY, mOneFragment);
}
if (mTwoFragment != null&&mTwoFragment .isAdded()) {
getSupportFragmentManager().putFragment(outState, TWO_FRAGMENT_KEY, mTwoFragment);
}
if (mFragmentThree != null&&mFragmentThree .isAdded()) {
getSupportFragmentManager().putFragment(outState, THREE_FRAGMENT_KEY, mFragmentThree);
}
if (mFragmentFour != null&&mFragmentFour .isAdded()) {
getSupportFragmentManager().putFragment(outState, FOUR_FRAGMENT_KEY, mFragmentFour);
}
super.onSaveInstanceState(outState);
}
3.getChildFragmentManager()
Activity:getFragmentManager()
在 Activity 嵌入 Fragment 时,需要使用 FragmentManager,通过 Activity 提供的 getSupportFragmentManager()
方法即可获取,用于管理 Activity 里面嵌入的所有一级 Fragment。
Fragment:getChildFragmentManager()
但是对于继续嵌套二级甚至三级 Fragment,即 Activity 嵌套多级 Fragment。此时在 Fragment 里管理子 Fragment 时,也需要使用到 FragmentManager。但是一定要使用 getChildFragmentManager()
方法获取 FragmentManager 对象。
4.Fragment + ViewPager
ViewPager 提供了两种页面适配器来管理不同 Fragment 之间的滑动切换:FragmentPagerAdapter
和 FragmentStatePagerAdapter
。
使用 FragmentPagerAdapter 时,ViewPager 中的所有 Fragment 实例常驻内存,当 Fragment 变得不可见时仅仅是视图结构的销毁,即调用了 onDestroyView() 方法。由于 FragmentPagerAdapter 内存消耗较大,所以适合少量静态页面的场景。
使用 FragmentStatePagerAdapter 时,当 Fragment 变得不可见,不仅视图层次销毁,实例也被销毁,即调用了 onDestroyView() 和 onDestroy() 方法,仅仅保存 Fragment 状态。相比而言, FragmentStatePagerAdapter 内存占用较小,所以适合大量动态页面,比如我们常见的新闻列表类应用。
Fragment 和activity交互
1,fragment调用activity,利用回调 activity继承接口OnFragmentInteractionListener
fragment中使用
public interface OnFragmentInteractionListener {
void onFragmentInteraction(int type);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
}
}
然后就能使用mListener进行操作
2,也可以在fragment的onActivityCreated里面实例化activity MainActivity activity =(MainActivity )getActivity();
1,懒加载的使用,使用懒加载FragmentActivity初始化需要 viewpager_container.setCurrentItem(currIndex);不然不会执行懒加载里面的数据初始化
/**
* @author fml
* created at 2016/6/24 15:17
* description:懒加载
*/
public abstract class LazyFragment extends Fragment {
//用于标记视图是否初始化
protected boolean isVisible;
private String TAG = this.getClass().getSimpleName();
//在onCreate方法之前调用,用来判断Fragment的UI是否是可见的
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
Log.i(TAG, "setUserVisibleHint:"+isVisibleToUser);
super.setUserVisibleHint(isVisibleToUser);
if (getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInvisible();
}
}
/**
* 视图可见
*/
protected void onVisible() {
lazyLoad();
}
/**
* 自定义抽象加载数据方法
*/
protected abstract void lazyLoad();
/**
* 视图不可见
*/
protected void onInvisible() {
}
}
一丶Fragment
1 、谈一谈 t Fragment 的生命周期?
参考回答:
Fragment 从创建到销毁整个生命周期中涉及到的方法依次
为:onAttach()
→onCreate()
→onCreateView()
→onActivityCreated()
→onStart()
→onR esume()
→onPause()
→onStop()
→onDestroyView()
→onDestroy()
→onDetach()
,其中和 Activity 有不少名称相同
作用相似的方法,而不同的方法有:
onAttach()
: 当 Fragment 和 Activity 建立关联时
调用;onCreateView()
: 当 fragment 创建视图调用,在
onCreate 之后;onActivityCreated()
: 当与 Fragment 相关联的
Activity 完成onCreate()
之后调用;onDestroyView()
: 在 Fragment 中的布局被移除时
调用;onDetach()
: 当 Fragment 和 Activity 解除关联时
调用;
2 、谈谈 y Activity 和 和 t Fragment 的区别?
参考回答:
相似点: 都可包含布局、可有自己的生命周期
不同点:
- Fragment 相比较于 Activity 多出 4 个回调周期,
在控制操作上更灵活; - Fragment 可以在 XML 文件中直接进行写入,也可以
在 Activity 中动态添加; - Fragment 可以使用 show()/hide()或者 replace()
随时对 Fragment 进行切换,并且切换的时候不会出
现明显的效果,用户体验会好;Activity 虽然也可
以进行切换,但是 Activity 之间切换会有明显的翻
页或者其他的效果,在小部分内容的切换上给用户
的感觉不是很好;
3 、Fragment 中 add 与 与 replace 的区别(Fragment 重叠)
参考回答:
- add 不会重新初始化 fragment,replace 每次都会。所以
如果在 fragment 生命周期内获取获取数据,使用 replace
会重复获取; - 添加相同的 fragment 时,replace 不会有任何变化,add
会报IllegalStateException
异常; - replace 先 remove 掉相同 id 的所有 fragment,然后在
add 当前的这个 fragment,而 add 是覆盖前一个
fragment。所以如果使用 add 一般会伴随 hide()和
show(),避免布局重叠; - 使用 add,如果应用放在后台,或以其他方式被系统销
毁,再打开时,hide()中引用的 fragment 会销毁,所以依
然会出现布局重叠 bug,可以使用 replace 或使用 add
时,添加一个 tag 参数;
4 、 getFragmentManager
、 getSupportFragmentManager
、
getChildFragmentManager
之间的区别?
参考回答:
getFragmentManager()
所得到的是所在 fragment 的 父容器
的管理器,getChildFragmentManager()
所得到的是在
fragment 里面 子容器的管理器, 如果是 fragment 嵌套
fragment,那么就需要利用getChildFragmentManager();
- 因为 Fragment 是 3.0 Android 系统 API 版本才出现的组
件,所以 3.0 以上系统可以直接调用getFragmentManager()
来获取FragmentManager()
对象,
而 3.0 以下则需要调用getSupportFragmentManager()
来
间接获取;
5 、FragmentPagerAdapter
与 与 FragmentStatePagerAdapter
的区别与使用场景
参考回答:
相同点 : 二者都继承 PagerAdapter
不同点 : FragmentPagerAdapter
的每个 Fragment 会持久的保存在 FragmentManager
中,只要用户可以返回到页面
中,它都不会被销毁。因此适用于那些数据 相对静态的
页,Fragment 数量也比较少的那种;FragmentStatePagerAdapter
只保留当前页面,当页面不
可见时,该 Fragment 就会被消除,释放其资源。因此适用
于那些 数据动态性较大、 占用内存较多,多 Fragment 的情
况;
二、Activity
1丶说下 Activity 生命周期?
参考解答: 在正常情况下,Activity 的常用生命周期就只有如下 7 个
onCreate()
: 表示 Activity 正在被创建,常用来 初始化工作,比
如调用setContentView
加载界面布局资源,初始化 Activity 所
需数据等;onRestart()
:表示 Activity 正在重新启动,一般情况下,当前Acitivty
从不可见重新变为可见时,OnRestart
就会被调用;onStart()
: 表示 Activity 正在被启动,此时 Activity 可见但不
在前台,还处于后台,无法与用户交互;onResume()
: 表示 Activity 获得焦点,此时 Activity 可见且在
前台并开始活动,这是与onStart
的区别所在;onPause()
: 表示 Activity 正在停止,此时可做一些 存储数据、
停止动画等工作,但是不能太耗时,因为这会影响到新 Activity
的显示,onPause
必须先执行完,新 Activity 的onResume
才会
执行;onStop()
: 表示 Activity 即将停止,可以做一些稍微重量级的回
收工作,比如注销广播接收器、关闭网络连接等,同样不能太耗
时;onDestroy()
: 表示 Activity 即将被销毁,这是 Activity 生命周
期中的最后一个回调,常做 回收工作、资源释放;
延伸: 从 整个生命周期来看,onCreate
和 onDestroy
是配对的,分别标识着 Activity 的创建和销毁,并且只可能有 一次调用; 从 Activity 是否可见来说,onStart
和 onStop
是配对的,这两个方法可能被 调用多次; 从 Activity 是否在前台来说,onResume
和 onPause
是配对的,这两个方法可能被 调用多次; 除了这种区别,在实际使用中没有其他明显区别;
2 、 Activity A 启动另一个 Activity B 会调用哪些方法?如果 B 是透明主题的又或则是个 DialogActivity
呢 ?
参考解答: Activity A 启动另一个 Activity B,回调如下
- Activity A 的
onPause()
→ Activity B 的onCreate()
→onStart()
→onResume()
→ Activity A 的onStop();
- 如果 B 是透明主题又或则是个
DialogActivity
,则不会回调 A 的onStop;
3 、说下 onSaveInstanceState()
方法的作用 ? ? 何时会被调用?
参考解答:
发生条件:异常情况下( 系统配置发生改变时导致 Activity被杀死并重新创建、资源内存不足导致低优先级的 Activity 被杀死)
- 系统会调用
onSaveInstanceState
来保存当前 Activity 的状态,
此方法调用在onStop
之前,与onPause
没有既定的时序关系; - 当 Activity 被重建后,系统会调用
onRestoreInstanceState
,
并且把onSave
(简称)方法所保存的 Bundle 对象 同时传参给onRestore
(简称)和onCreate()
,因此可以通过这两个方法判断Activity 是否被重建,调用在onStart
之后;
4 、说下 y Activity 的四种启动模式、应用场景 ?
参考回答:
- standard 标准模式: 每次启动一个 Activity 都会重新创建一个
新的实例,不管这个实例是否已经存在,此模式的 Activity 默认
会进入启动它的 Activity 所属的任务栈中; singleTop
栈顶复用模式: 如果新 Activity 已经位于任务栈的栈顶,那么此 Activity 不会被重新创建,同时会回调onNewIntent
方法,如果新 Activity 实例已经存在但不在栈顶,那么Activity 依然会被重新创建;- singleTask 栈内复用模式: 只要 Activity 在一个任务栈中存在,那么多次启动此 Activity 都不会重新创建实例,并回调
onNewIntent
方法,此模式启动 Activity A,系统首先会寻找是
否存在 A 想要的任务栈,如果不存在,就会重新创建一个任务
栈,然后把创建好 A 的实例放到栈中; singleInstance
单实例模式: 这是一种加强的singleTask
模
式,具有此种模式的 Activity 只能单独地位于一个任务栈中,且
此任务栈中只有唯一一个实例;
5 、了解哪些 Activity 常用的标记位 Flags ?
参考回答:
- FLAG_ACTIVITY_NEW_TASK : 对应
singleTask
启动模式,其效果和在 XML 中指定该启动模式相同; - FLAG_ACTIVITY_SINGLE_TOP : 对应
singleTop
启动模式,其效果和在 XML 中指定该启动模式相同; - FLAG_ACTIVITY_CLEAR_TOP : 具有此标记位的 Activity,当它启动时,在同一个任务栈中所有位于它上面的 Activity 都要出栈。这个标记位一般会和
singleTask
模式一起出现,在这种情况下,被启动 Activity 的实例如果已经存在,那么系统就会回调onNewIntent
。如果被启动的 Activity 采用 standard 模式启动,那么它以及连同它之上的 Activity 都要出栈,系统会创建新的Activity 实例并放入栈中; - FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS : 具有这个标记的Activity 不会出现在历史 Activity 列表中;
6 、说下 Activity 跟 跟 window , view 之间的关系?
参考回答:
Activity 创建时通过 attach()
初始化了一个 Window 也就是PhoneWindow
,一个 PhoneWindow
持有一个 DecorView
的实例,DecorView
本身是一个 FrameLayout
,继承于 View,Activty
通过setContentView
将 xml
布局控件不断 addView()
添加到 View 中,最终显示到 Window 于我们交互;
7 、横竖屏切换的 y Activity 生命周期变化?
参考回答:
- 不设置 Activity 的
android:configChanges
时,切屏会销毁当前Activity,然后重新加载调用各个生命周期,切横屏时会执行一
次,切竖屏时会执行两次;onPause()
→onStop()
→onDestory()
→onCreate()
→onStart()
→onResume()
- 设置 Activity 的
android:configChanges=" orientation"
,经过
机型测试- 在 Android5.1 即 即 API 3 23 级别下,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
- 在 Android9 即 即 API 8 28 级别下,切屏不会重新调用各个生命周期,只会执行
onConfigurationChanged
方法 - 官方纠正后,原话如下
如果您的应用面向 Android 2 3.2 即 即 API 级别 3 13 或更
高级别(按照minSdkVersion
和targetSdkVersion
)