Fragment生命周期
onCreateView() :每次加载Fragment的时候会执行该方法、配对的生命周期是: onDestroyView()
onCreateView() :onCreateView()方法执行完后进行执行,代表View绘制完成
onResume() :该Fragment被执行了show操作、或者是该页面从后台显示到前台,或者是其依赖的Activity的生命周期的改变;那种ViewPager+Fragment的那种,ViewPager切换的时候,其Fragment是不执行onResume和onPause的,因为其Activity的声明周期没有改变,而且也没有执行hide和show操作,其移动就是将该Fragment进行了移动,并没有移出到后台?所以没有执行Fragment的生命周期、、、、、其实Fragment的生命周期都是根据Activity来的,除了自己的创建、尤其是onResume和onPause都是根据Activity的声明周期的onResume和onPause、、、、真正的判断实现的方法有两个:setUserVisibleHint()和onHiddenChanged()—针对show\hide的Fragment
ViewPager+Fragment “预”加载方式解析
viewPager.setOffscreenPageLimit(x): 不设置默认ViewPager会预加载相邻的1个Fragment,当切换Fragment时之前相邻的Fragment会执行onDestroyView()将Fragment销毁,当再次切换到该Fragment时其会重新生成该Fragment,也就是重新调用onCreateView()方法,也就是每次点击非相邻的Tab会重新加载渲染一次Fragment
viewPager.setOffscreenPageLimit(n):设置值后,一般设置fragmentList-1,这样其切换Fragment的时候所有的Fragment不会重走生命周期,也就是不会走onDestroyView()和onCreateView()进行Fragment的重复创建,这种的话刚启动加载第一个Fragment的时候,其余的都会执行onCreateView()、、onCreateView()方法进行预加载,当然这种当Activity执行生命周期onPause时,所有的都会执行onPause
其实ViewPager就是ViewGroup就是一个View的容器,类似于容器也就是说不管内部有多少View其都会“一次全部”加载到容器内,也就是不管现在在屏幕中的还是没有在屏幕中显示的View,其已经全部加载到该容器中了,不会因为你不在该屏幕上显示就说你没有加载到ViewGroup中,排除外来因素(手动进行ViewGroup的移出添加、或者是手动调用内部View的相关方法),勉强解释为什么setOffscreenPageLimit(n),切换Fragment的时候,不走Fragment的声明周期
ViewPager+Fragment “懒”加载方式解析
Fragment的是否显示在前台方法(onResume\onPause在上边的那种情况代表不了)
setUserVisibleHint(boolean isVisibleToUser): isVisibleToUser为ture表示该Fragment在前台展示,isVisibleToUser为false表示该Frament没有在前台展示(并不代表其跑到了后台,如果都是这样那么Fragment的onResume和onPause就可以判断了),在ViewPager+Fragment模式下设置了setOffscreenPageLimit(n)并且切换Tab的时候一样会改变该值
setUserVisibleHint: 该方法有可能会被多次回调,也就是说在判断是否显示在前台前,最好还是判断一下该View是否加载完成,然后在决定是否进行网络请求;当然为了防止每次点击都加载数据,还可以添加个别的变量isFirst来判断是否是第一次加载
这种一般设置在BaseFragment中,向外部抛出abstract方法
public abstract void fragmentIsVisible(boolean isVisibleToUser);
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
isViewCreated = true;
isFirstCreate = true;
doLazyLoad();
}
..............................
/**
* 返回True 表示当前View是否加载到窗口、就是是否是当前窗口展示
*
* @param isVisibleToUser
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//该方法有可能会调用多次、包括有可能View还没创建就进行调用、、、防止重复加载、防止View还没创建就进行View的调用操作
isViewVisible = true;
doLazyLoad();
} else {
isViewVisible = false;
}
}
......................................
//需要区分是否是第一次加载、防止每次切换都进行数据的调用 更新
private void doLazyLoad() {
if (isViewCreated && isViewVisible) {
if (isFirstCreate) {
fragmentIsVisible(true);
isFirstCreate = false;
}
} else {
fragmentIsVisible(false);
}
}
ViewPager 的进制左右滑动
dispatchTouchEvent(MotionEvent ev):不变还是之前的 return super.dispatchTouchEvent(ev)-支持向下分发
onInterceptTouchEvent(MotionEvent ev):改变return false;不进行事件拦截,进行向底部View传递
onTouchEvent(MotionEvent ev) :改变 return false:底部View没有响应消费的话,事件回传过来自己也不进行消费,再往外传,不进行滑动响应