Android:Flutter——Bug Or 特性?一个属性引起的绘制流程的问题

前言

文末有福利!!!

在前面的文章中,提到了我会将翻页动画集成进LayoutManager中,在此过程中遇到了一个有点意思的问题;

如果在最普通的ListView中,仅仅提供itemBuilder等提供item所需的必要部分;其他属性并不作修改;

修改其中的paint方法,如果将saveLayer的BlendMode改为dst,下面这段代码的运行结果是?

image.png

结果正如预想中的那样,由于dst属性生效,所以展示的其他页面,比如说第一页:

image.png

下面有点意思的东西来了,如果我解开上面的paintChild部分的注释,讲道理,dst应该接着生效吧,其实不然,解开注释之后的效果,竟然是drawColor的clear效果,一片背景的黑色:

image.png

不过这个问题只需要修改ListView的一个属性,将其改为false即可:

image.png

那么问题来了,这个addRepaintBoundaries都干了什么?为什么saveLayer这种新建图层的操作的效果都给强制取消掉了?

分析

在前面的文章中已经提到过,addRepaintBoundaries 的唯一作用就是给Item包一层 RepaintBoundary;那问题就出自这块了;

而出现这个问题的另一个必要因素就是context.paintChild 方法,那么看一下这个方法:

image.png

在paintChild方法中,抛开assert 部分,剩下的就一处 if else 判断,而且正好是跟 RepaintBoundary 有关的 isRepaintBoundary 判断;

child._paintWithContext 方法自不用多说,其中就是调用child自己本身的paint方法,属于挺正常的逻辑;而这个stopRecordingIfNeeded 和 _compositeChild 就应该是问题所在;

第一个stopRecordingIfNeeded,根据注释,无非是停止绘制内容,而非改变绘制,所以可以排除;那么第二个_compositeChild 方法就是问题所在了;

而其内容也不多:

image.png

总结一下:如果child需要重绘,那么调用 repaintCompositedChild,否则就调用 appendLayer;

而这个 repaintCompositedChild 应该是调不到的,child一直不需要重绘,那就需要再看下这个 appendLayer 方法:

image.png

这里出现了Flutter的第四棵树的部分———— Layer 树,也就是最后一步,最终传给引擎层的树;(一般我们只关注前三棵树……没想到也有来看第四棵树的一天……)

而这个方法所做的事非常简单,就是将原来的Layer树结构改变,解绑原Layer,并加入到心的ContaienrLayer中;

而这个ContaienrLayer出自也很简单,就一处:

image.png

那么回到最开始的paint方法,串联一下,如果由RepaintBoundary,所做的事就是将RepaintBoundary的layer树加到父widget对应的layer中,就这么简单~

但是问题来了,如果我没错的话,这里有个问题:

canvas呢,我为canvas创建的layer呢?是这样被新add上去的layer替换掉了么?

image.png

个人感觉问题就在这里,由于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即可免费领取↓↓↓

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值