ViewPagerIndicator源码解读
来源:互联网 发布:开源php cms 编辑:程序博客网 时间:2024/06/07 02:39
ViewPagerIndicator源码解读
1.TabMainActivity最先执行,而且在Adapter里new了FirstLayerFragment因为FirstLayerFragment继承LazyFragment,LazyFragment继承BaseFragment,BaseFragment继承Fragment,现在继续看执行哪里
2.主要是区分setUserVisibleHint和onCreateView这两个方法的先后顺序。先执行setUserVisibleHint方法,而代码中却有如下判断
public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser && !isInit && getContentView() != null) { //没有初始化才会走这里。而且不是说setUserVisibleHint方法比初始化方法前面执行吗,为什么首页没有执行这里 //因为getContentView()==null不符合条件 Log.d("xiao", "这个时候不是首页在这里加载数据"); isInit = true; onCreateViewLazy(savedInstanceState); onResumeLazy(); } if (isInit && getContentView() != null) {//如果初始化过了,才会走这里 if (isVisibleToUser) { Log.d("xiao2", "初始化过了走这里"); isStart = true; onFragmentStartLazy(); } else { Log.d("xiao22", "初始化过了走这里"); isStart = false; onFragmentStopLazy(); } }}
,首页满足前面两个条件但是首页并没有setContentView所以首页的setUserVisibleHint方法因为不符合条件并没有执行完全,所以首页是没走完setUserVisibleHint却走完了onCreateView方法,看下onCreateView代码首页执行如下:
if (getUserVisibleHint() && !isInit) {//如果fragment中的UI已经可见,而且初始化为false //所以划到哪个fragment才会加载一次这个fragment,但是为什么会执行两次。和上面问题一样翻倍了 //初始化时,只有index=0的fragment才会执行这里,且会执行两次。 Log.d("xiao11", "这个时候isInit==" + isInit + "且getUserVisibleHint()==" + getUserVisibleHint()); isInit = true;//则将初始化改为true //这个地方执行onCreateViewLazy方法,是专门为首页服务的(也可以说是为第一个展示在屏幕上的fragment服务的) onCreateViewLazy(savedInstanceState);//在子Fragment中执行创建lazyView的方法, //只有在这里才会执行onCreateViewLazy方法,加载数据,首页数据在这里加载,那么不是首页数据在哪里加载呢?}
易知此时,做了两件事。一,把isInit赋值为true;二,执行onCreateViewLazy方法加载了首页数据。
那么非首页的fragment呢?此时也会先执行setUserVisibleHint后执行onCreateView方法。由上面代码可知,非首页显然不满足isVisibleToUser这个条件,因为非首页这个时候都是不可见的。所以非首页也是没有压根就没有执行setUserVisibleHint方法,而是继续执行onCreateView方法。继续看onCreateView代码:
else {//如果没有同时满足fragment中的UI已经可见和初始化为false //初始化时,其他三个没有划到的fragment会执行这里,且会执行两次 //这个时候不执行加载数据的逻辑,只是弄一个预加载的页面弄上去 //这个时候还是都没有进行初始化的,isInit==false Log.d("xiao12", "这个时候isInit==" + isInit + "且getUserVisibleHint()==" + getUserVisibleHint()); LayoutInflater layoutInflater = inflater; if (layoutInflater == null) { layoutInflater = LayoutInflater.from(getApplicationContext()); } layout = new FrameLayout(layoutInflater.getContext());//那么首先创建一个新的FrameLayout控件 View view = getPreviewLayout(layoutInflater, layout); if (view != null) { layout.addView(view); } layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams .MATCH_PARENT)); super.setContentView(layout);//这个是为了设置预加载页面,终于知道这玩意有啥用了,为了区分 //首页和非首页的。因为首页没有setContentView,所以不会执行setUserVisibleHint里的onCreateViewLazy}
这个时候由于不满足getUserVisibleHint()这个条件,所以非首页在onCreateView方法中执行以上代码,目的是为了给非首页的fragment加一个contentview。
3.接下来分析,滑动fragment页面会怎么执行代码。这个阶段已经过了初始化的阶段了,即onCreateView方法不会再执行了。但是setUserVisibleHint()方法还是会执行,为什么呢?请看代码注释翻译为中文就是当碎片对于用户可见时通知系统,所以还是会执行。看上面代码,
注意这个时候fragment的条件是:1.可见了;2.还有没有进行初始化(因为这个时候只有首页进行了初始化);3.getContentView也不会空;
所以综上三个条件,此时满足if条件,且将isInit赋值true,并执行加载数据方法onCreateViewLazy()。
4.现在又有一个问题,就是setUserVisibleHint()方法会滑一个fragment就执行一次,那就会重复加载数据。这个时候isInit布尔值就起作用了,纵观代码发现isInit=true;总是伴随着onCreateViewLazy()同时出现,所以只要if(!isInit)就可以防止重复加载了。
总结:
LazyFragment通过三个boolean值分别是isInit、isVisibleToUser、getContentView() != null完美解决了两个问题:
1.初始化阶段,阻止了先执行setUserVisibleHint()方法,主要是里面的onCreateViewLazy()加载数据的方法,让onCreateView方法优先执行;
2.通过isInit布尔值,防止重复执行onCreateViewLazy()方法,重复加载数据;
if (!isEnabled() || mReturningToStart || canChildScrollUp() || mRefreshing || mNestedScrollInProgress) { // Fail fast if we're not in a state where a swipe is possible return false;}
0 0
- ViewPagerIndicator源码解读
- ViewPagerindicator 源码解析
- ViewPagerindicator 源码解析
- ViewPagerindicator 源码解析
- ViewPagerindicator 源码解析
- ViewPagerindicator 源码解析
- ViewPagerindicator 源码解析
- Jake Wharton之ViewPagerIndicator解读预备役
- ViewPagerIndicator-master源码分析 1
- ViewPagerIndicator-master源码分析 2
- ViewPagerIndicator-master源码分析 3
- SlidingMenu、xUtils、ViewPagerindicator源码解析
- ViewPagerIndicator
- ViewPagerIndicator
- ViewPagerIndicator
- ViewPagerIndicator
- ViewPagerIndicator
- ViewPagerIndicator
- Java 8 实战 阅读记录
- Modernizr.js介绍与使用
- 微信开发者工具无法使用 error:unable to verify the first certificate
- 这交互炸了(三):闪屏页是像云一样消失的
- Android中设备配置和备选资源的概念
- ViewPagerIndicator源码解读
- ansible安装方法
- HDU4247 A Famous ICPC Team
- sqoop中的增量更新
- Spring常用注解汇总
- phpstorm 快捷键
- 计算机词汇大全
- myeclipse常见错误集锦 及解决方案
- window.open() POST 方式提交json数据,以及后台的json序列化为对象