前言
文末有福利!!!
在前面的文章中,提到了我会将翻页动画集成进LayoutManager中,在此过程中遇到了一个有点意思的问题;
如果在最普通的ListView中,仅仅提供itemBuilder等提供item所需的必要部分;其他属性并不作修改;
修改其中的paint方法,如果将saveLayer的BlendMode改为dst,下面这段代码的运行结果是?
结果正如预想中的那样,由于dst属性生效,所以展示的其他页面,比如说第一页:
下面有点意思的东西来了,如果我解开上面的paintChild部分的注释,讲道理,dst应该接着生效吧,其实不然,解开注释之后的效果,竟然是drawColor的clear效果,一片背景的黑色:
不过这个问题只需要修改ListView的一个属性,将其改为false即可:
那么问题来了,这个addRepaintBoundaries
都干了什么?为什么saveLayer这种新建图层的操作的效果都给强制取消掉了?
分析
在前面的文章中已经提到过,addRepaintBoundaries 的唯一作用就是给Item包一层 RepaintBoundary;那问题就出自这块了;
而出现这个问题的另一个必要因素就是context.paintChild 方法,那么看一下这个方法:
在paintChild方法中,抛开assert 部分,剩下的就一处 if else 判断,而且正好是跟 RepaintBoundary 有关的 isRepaintBoundary 判断;
child._paintWithContext 方法自不用多说,其中就是调用child自己本身的paint方法,属于挺正常的逻辑;而这个stopRecordingIfNeeded 和 _compositeChild 就应该是问题所在;
第一个stopRecordingIfNeeded,根据注释,无非是停止绘制内容,而非改变绘制,所以可以排除;那么第二个_compositeChild 方法就是问题所在了;
而其内容也不多:
总结一下:如果child需要重绘,那么调用 repaintCompositedChild,否则就调用 appendLayer;
而这个 repaintCompositedChild 应该是调不到的,child一直不需要重绘,那就需要再看下这个 appendLayer 方法:
这里出现了Flutter的第四棵树的部分———— Layer 树,也就是最后一步,最终传给引擎层的树;(一般我们只关注前三棵树……没想到也有来看第四棵树的一天……)
而这个方法所做的事非常简单,就是将原来的Layer树结构改变,解绑原Layer,并加入到心的ContaienrLayer中;
而这个ContaienrLayer出自也很简单,就一处:
那么回到最开始的paint方法,串联一下,如果由RepaintBoundary,所做的事就是将RepaintBoundary的layer树加到父widget对应的layer中,就这么简单~
但是问题来了,如果我没猜错的话,这里有个问题:
canvas呢,我为canvas创建的layer呢?是这样被新add上去的layer替换掉了么?
个人感觉问题就在这里,由于saveLayer这种都是native方法,没有直接去看,所以以上猜测纯属脑补;
但是考虑到 saveLayer 这种native方法应该不至于跨语言跟dart层共享数据,我这猜测正确的概率,大概55开???
总之可以肯定的是,去掉RepaintBoundary,就能正常处理;至于这块是人为疏漏,忘记了saveLayer的部分,还是就这么设计的,那就是另一回事了…………不过由此导致的困扰确实是真实存在的…………
结尾
这个问题花了2小时,甚至摸鱼时间都用来解决这个问题……因此今天也就将原来逻辑移到LayoutManager中;就不放新进度效果图了,进度约等于0;
不过往好处想想,找出了解决方案,不至于半夜床中惊坐起,自问此题如何解;
移到LayoutManager中;就不放新进度效果图了,进度约等于0;
不过往好处想想,找出了解决方案,不至于半夜床中惊坐起,自问此题如何解;
最后
有小伙伴私信问Compose的问题,好不好用啊,现在要不要学啊?
其实答案很简单,自从谷歌2019年公布了声明式UI框架Jetpack Compose后,两年多的时间,各种大力宣传,和大量资源的倾斜,API功能都趋于稳定了。
至于好不好用,各种用过的同行都是持肯定态度的。优势大概就是这四点:
强大的工具和直观的Kotlin API
简化并加速了Android上的UI开发
可以帮助开发者用更少更直观的代码创建View
有更强大的功能,以及还能提高开发速度
这么大的优势,毋庸置疑,肯定是要学的嘛,而且越快掌握越好。别等刀架到脖子上了,才去练金钟罩。
至于怎么快速上手,可以给大家免费分享一份**《Jetpack Compose 完全开发手册》**,手把手教大家从入门到精通。
有需要的话可以添加下面二维码回复JJ即可免费领取↓↓↓
第一章 初识 Jetpack Compose
-
为什么我们需要一个新的UI 工具?
-
Jetpack Compose的着重点
加速开发
强大的UI工具
直观的Kotlin API
- API 设计
- Compose API 的原则
一切都是函数
顶层函数(Top-level function)
组合优于继承
信任单一来源
- 深入了解Compose
Core
Foundation
Material
- 插槽API
第二章 Jetpack Compose构建Android UI
- Android Jetpack Compose 最全上手指南
Jetpack Compose 环境准备和Hello World
布局
使用Material design 设计
Compose 布局实时预览
……
- 深入详解 Jetpack Compose | 优化 UI 构建
Compose 所解决的问题
Composable 函数剖析
声明式 UI
组合 vs 继承
封装
重组
……
- 深入详解 Jetpack Compose | 实现原理
@Composable 注解意味着什么?
执行模式
Positional Memoization (位置记忆化)
存储参数
重组
……
第三章 Jetpack Compose 项目实战演练(附Demo)
- Jetpack Compose应用1
开始前的准备
创建DEMO
遇到的问题
- Jetpack Compose应用2
- Jetpack Compose应用做一个倒计时器
数据结构
倒计时功能
状态模式
Compose 布局
绘制时钟
- 用Jetpack Compose写一个玩安卓App
准备工作
引入依赖
新建 Activity
创建 Compose
PlayTheme
画页面
底部导航栏
管理状态
添加页面
- 用Compose Android 写一个天气应用
开篇
画页面
画背景
画内容
……
- 用Compose快速打造一个“电影App”
成品
实现方案
实战
不足
……
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
有需要的话可以添加下面二维码回复JJ即可免费领取↓↓↓