如何在两个ThemeData类间插值实现明暗主题平滑过渡
亮暗色主题平滑插值实现思路
核心是基于动画进度值对主题类属性做递归插值,整体思路分4步:
- 先定义基础类型的插值规则
先覆盖所有主题会用到的基础变量类型的插值逻辑:- 颜色类:直接使用线性插值算法,根据0-1的进度值计算起始色到目标色的中间色,绝大多数开发框架都有内置的
Color.lerp方法可以直接调用 - 数值类(圆角、边距、字号、透明度等):直接通过公式
起始值 + (目标值 - 起始值) * 进度值计算中间值 - 布尔、枚举类:一般选择进度到0.5时直接切换状态,有特殊需求也可以配合透明度做渐变过渡
- 颜色类:直接使用线性插值算法,根据0-1的进度值计算起始色到目标色的中间色,绝大多数开发框架都有内置的
- 实现自定义类的递归插值逻辑
针对ThemeData这类包含多层子属性的自定义类,为其编写对应的lerp静态方法,方法内遍历所有需要过渡的属性:- 基础类型属性直接调用对应类型的插值方法
- 子自定义类属性(比如
TextStyle、ButtonStyle等)调用该类自己的lerp方法做深层插值
逐层递归后即可计算出任意进度下的完整中间主题实例
- 绑定动画驱动实现过渡效果
搭配系统的动画框架实现平滑过渡:- 触发主题切换时,启动一个固定时长(通常200-300ms)的动画控制器,输出0到1的实时进度值
- 每次进度值更新时,调用前面写的lerp方法生成当前进度对应的中间
ThemeData实例 - 将中间实例实时替换为全局生效的主题配置,UI就会自动刷新呈现过渡效果
- 可选性能优化
如果主题类属性量级较大,可以增加差值判断逻辑:仅对起始主题和目标主题中取值不同的属性做插值计算,取值相同的属性直接复用原有值,减少不必要的计算开销
内容的提问来源于stack exchange,提问作者user16190778
相关产品推荐
相关产品推荐

