MiuiSystemUI_X Folme 动画库集成调研文档
项目: MiuiSystemUI_X
调研日期: 2026-04-28
Folme 版本: 4.0.0-alpha03
调研范围: 依赖架构、核心 API、项目封装层、使用模式、模块覆盖
1. 概述
Folme 是小米 MiuiX 组件库中的声明式状态驱动动画框架,基于物理弹簧模型实现。在 MiuiSystemUI_X 项目中,Folme 作为唯一的动画基础设施,完全替代了 Android 原生的 ObjectAnimator/ValueAnimator,覆盖了锁屏、通知、控制中心、状态栏等全部核心 UI 模块。
使用规模统计:
| 指标 | 数据 |
|---|---|
| 引用文件数 | 149 个 .java/.kt 文件 |
| import 语句数 | 776 条 |
| 自定义封装类 | 8 个核心工具类 |
| 动画类型定义 | 12 种通知系统专用类型 |
2. 依赖架构
2.1 制品形态
Folme 以预编译 AAR 形式集成,存放在项目本地:
packages/SystemUI/miuix_library/prebuilts-alpha/
└── miuix/folme/folme/4.0.0-alpha03/
├── folme-4.0.0-alpha03.aar (399KB)
└── AndroidManifest.xml (minSdk=21, meta-data folme=2.0)
2.2 依赖链
在 Android.bp (L52-75) 中定义的静态依赖关系:
miuix.folme (4.0.0-alpha03)
├── miuix.animation (4.0.0-alpha03) ← 底层物理弹簧/插值动画引擎
├── miuix.devicebaseinfo ← 设备信息(动画参数可能按设备适配)
├── androidx.collection
└── androidx.lifecycle-common
Folme 是
miuix.animation的上层封装。miuix.animation提供原始的弹簧物理模型和属性插值能力,Folme 在其上构建了状态机、触摸反馈、可见性动画等高层抽象。
2.3 多模块引用策略
| 模块 | 引用方式 | 说明 |
|---|---|---|
Base | api libs.miuix.folme | 使用 api 传递暴露,确保所有依赖 Base 的模块自动获得 Folme |
miuiutils | implementation libs.miuix.folme | 模块内部使用 |
ControlCenter | implementation libs.miuix.folme | 模块内部使用 |
QuickAppPanel | implementation libs.miuix.folme | 同时 exclude group: 'miuix.folme' 去除其他依赖传递的重复 |
SystemUI (主模块) | implementation libs.miuix.folme | 同上,通过 exclude 避免冲突 |
去重机制:多个 miuix 组件(如 miuix.springback、miuix.smooth)可能传递依赖 folme。项目通过在引入这些组件时添加 exclude group: 'miuix.folme', module: 'folme' 统一到顶层声明的版本,避免类路径冲突。
3. Folme 核心 API
3.1 入口类 miuix.animation.Folme
| 静态方法 | 签名 | 用途 |
|---|---|---|
use(View) | Folme.use(view): IFolme | 绑定 View,获取或创建动画实例(懒初始化) |
useAt(View) | Folme.useAt(view): IFolme | 同 use,语义上用于已初始化的 View |
get(View) | Folme.get(view): IFolme? | 仅获取已有实例,无则返回 null(不创建) |
useValue(Any) | Folme.useValue(target): IStateStyle | 创建非 View 绑定的值动画实例 |
3.2 核心接口 IFolme
IFolme 是 View 级别的动画控制中心,提供多种动画控制器:
| 控制器方法 | 返回类型 | 用途 |
|---|---|---|
state() | IStateStyle | 核心属性状态动画(alpha、scale、translation 等) |
touch() | ITouchStyle | 触摸反馈动画(按下缩放、色调变化) |
hover() | IHoverStyle | 鼠标/手写笔悬浮效果 |
visible() | IVisibleStyle | 可见性切换动画(show/hide/toggle) |
3.3 状态动画 IStateStyle
IStateStyle 是使用最频繁的接口,核心操作:
// 动画过渡到目标值(弹簧/插值曲线由 AnimConfig 决定)
folme.state().to(FloatProperty property, float value, AnimConfig config)
// 立即设置目标值(无动画,但更新内部状态)
folme.state().setTo(FloatProperty property, float value)
// 取消当前动画并强制重置到指定值
folme.state().resetTo(FloatProperty property, float value)
// 取消指定属性或全部动画
folme.state().cancel(FloatProperty property)
folme.state().cancel()3.4 动画配置 AnimConfig
AnimConfig config = new AnimConfig();
config.setEase(EaseManager.EaseStyle ease); // 设置缓动曲线
config.addListeners(TransitionListener listener); // 动画生命周期回调
config.setTag(Object tag); // 标记动画状态3.5 缓动系统 FolmeEase
Folme 提供物理弹簧和传统缓动两类:
FolmeEase.linear(duration) // 线性(传统时间驱动)
FolmeEase.spring(damping, stiffness) // 弹簧(物理驱动,无固定时长)
// EaseManager.EaseStyle 抽象,支持自定义3.6 属性系统 ViewProperty
预定义的 View 属性常量(miuix.animation.property.ViewProperty):
ALPHA, TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z,
SCALE_X, SCALE_Y, ROTATION, ROTATION_X, ROTATION_Y, X, Y
支持自定义 FloatProperty<T>,项目中自定义了 BLUR_PROPERTY。
3.7 生命周期回调 TransitionListener
new TransitionListener() {
void onBegin(Object toTag) // 动画开始
void onCancel(Object toTag) // 动画被取消(新动画中断或手动 cancel)
void onComplete(Object toTag) // 动画自然完成
}4. 项目封装层
项目在 Folme 原始 API 之上构建了 4 层渐进式封装,从简单到复杂逐步增加功能:
4.1 第 1 层:Kotlin 扩展属性
文件: packages/SystemUI/miuiModules/miuiutils/src/main/java/com/miui/systemui/animation/Folme.kt
// View 扩展属性 —— 简化 Folme.use(view) 调用
val View.folme: IFolme get() = Folme.use(this)
fun View.folme(): IFolme? = Folme.get(this)
// FolmeObject 扩展 —— 让非 View 对象持有 Folme 实例
val FolmeObject.folme: IFolme get() = Folme.use(this)
// FolmeObject 工厂函数 + Kotlin 委托模式
fun FolmeObject() = object : FolmeObject {
private var folmeImpl: ObjectFolmeImpl? = null
override fun setFolmeImpl(folmeImpl: ObjectFolmeImpl?) { this.folmeImpl = folmeImpl }
override fun folme() = folmeImpl
}设计意图:
- 消除 Java 样板代码,在 Kotlin 中直接
view.folme.state().to(...) - 通过
FolmeObject()工厂 + Kotlin 委托(by),任何控制器类都能安全持有ObjectFolmeImpl引用,避免手动管理 Folme 实例生命周期导致内存泄漏
使用示例:
class SampleFolmeController : FolmeObject by FolmeObject() {
fun sampleFunc() {
folme.to(...) // 通过委托直接访问
}
}4.2 第 2 层:工具类
文件: packages/SystemUI/miuiModules/Base/src/com/miui/systemui/util/FolmeUtils.kt
object FolmeUtils {
private val INSTANT_EASE = FolmeEase.linear(0) // 零时长线性缓动
fun useValue(target: Any, defaultMinVisible: Float = Float.MAX_VALUE): IStateStyle =
Folme.useValue(target).apply {
(this as? IFolmeStateStyle)?.target?.setDefaultMinVisibleChange(defaultMinVisible)
}
@JvmStatic
fun instantTo(folme: IStateStyle?, tag: Any?, oneTimeConfig: AnimConfig? = null) {
if (folme != null && tag != null) {
val config = AnimConfig(oneTimeConfig).setEase(INSTANT_EASE)
folme.to(tag, config)
}
}
}设计意图:
instantTo:用FolmeEase.linear(0)实现”瞬间过渡”。虽然动画时长为 0,但仍走 Folme 的状态管理管线和回调机制,保证内部状态一致性。这比直接setTo更安全,因为会触发TransitionListener回调链useValue:封装了minVisibleChange配置,控制动画的最小可见变化量(低于此阈值的变化不触发渲染),用于性能优化
4.3 第 3 层:属性动画系统(StatusBar 模块)
这是项目最核心的封装层,由 3 个类协作:
4.3.1 FolmeAnimatableProperty —— 可动画属性抽象
文件: packages/SystemUI/miuiModules/StatusBar/src/main/java/com/android/systemui/statusbar/anim/FolmeAnimatableProperty.kt
interface FolmeAnimatableProperty {
val animatorTag: Int // View.setTag 的 key,用于追踪动画状态
val viewProperty: FloatProperty<View> // Folme 属性引用
companion object {
val ALPHA = from(ViewProperty.ALPHA, R.id.folme_alpha_animator_tag)
val TRANSLATION_X = from(ViewProperty.TRANSLATION_X, R.id.folme_translation_x_animator_tag)
val SCALE_X = from(ViewProperty.SCALE_X, R.id.folme_scale_x_animator_tag)
val SCALE_Y = from(ViewProperty.SCALE_Y, R.id.folme_scale_y_animator_tag)
val X = from(ViewProperty.X, R.id.folme_x_animator_tag)
val BLUR = from(BLUR_PROPERTY, R.id.folme_blur_animator_tag) // 自定义模糊属性
}
}关键设计:将 FloatProperty 和 animatorTag(资源 ID)绑定为一个单元。animatorTag 是通过 View.setTag(tag, info) / View.getTag(tag) 机制存储在 View 上的,用于追踪每个属性的动画状态。这种设计让动画状态跟随 View 生命周期,无需外部数据结构管理。
自定义 BLUR 属性:
val BLUR_PROPERTY = object : FloatProperty<View>("status_bar_icon_blur", 1f) {
override fun setValue(target: View, value: Float) {
if (target is IBlurEffect) target.blurRadius = ceil(value).toInt()
}
override fun getValue(target: View): Float {
return if (target is IBlurEffect) target.blurRadius.toFloat() else 0f
}
}通过 IBlurEffect 接口实现模糊效果的动画化,展示了 Folme 自定义属性的扩展能力。
4.3.2 FolmeProperties —— 动画声明 Builder
文件: packages/SystemUI/miuiModules/StatusBar/src/main/java/com/android/systemui/statusbar/anim/FolmeProperties.kt
class FolmeProperties {
var config: AnimConfig? = null
val animatedProperties = mutableMapOf<FloatProperty<View>, IAnimationCallback?>()
fun animateAlpha(callback: IAnimationCallback? = null): FolmeProperties
fun animateScale(callback: IAnimationCallback? = null): FolmeProperties // 同时设置 SCALE_X + SCALE_Y
fun animateScaleX(callback: IAnimationCallback? = null): FolmeProperties
fun animateScaleY(callback: IAnimationCallback? = null): FolmeProperties
fun animateTranslationX(callback: IAnimationCallback? = null): FolmeProperties
fun animateX(callback: IAnimationCallback? = null): FolmeProperties
fun animateBlur(callback: IAnimationCallback? = null): FolmeProperties
}Fluent Builder 模式,声明哪些属性参与本次动画,并可为每个属性单独绑定 IAnimationCallback(onStart/onFinish)。
4.3.3 FolmePropertyAnimator —— 动画调度器(核心)
文件: packages/SystemUI/miuiModules/StatusBar/src/main/java/com/android/systemui/statusbar/anim/FolmePropertyAnimator.kt
这是整个封装层最复杂的类,单例对象,负责所有属性动画的启动、更新、取消逻辑。
startAnimation 核心流程:
1. 从 View Tag 读取 AnimateTagInfo(上一次动画的状态)
↓
2. 目标值去重:如果新目标值 == 上次目标值 → 跳过(避免重复启动)
↓
3. 分支判断:
├── properties 未包含该属性 && 已有动画 → 复用已有 IFolme 实例,直接 to() 更新目标值(平滑衔接)
├── properties 未包含该属性 && 无动画 → 直接 property.set() 设值(无动画)
├── 当前值 == 目标值 → cancel() + 触发 onComplete 回调
└── 其他 → 创建新 TransitionListener,通过 folme.state().to() 启动
↓
4. 将 AnimateTagInfo(folme, endValue, easeStyle) 写入 View Tag
AnimateTagInfo 数据类:
class AnimateTagInfo(
var folme: IFolme?, // 持有的 Folme 实例
var endValue: Float?, // 目标值
var style: EaseManager.EaseStyle? // 缓动曲线(用于后续复用)
)其他方法:
| 方法 | 用途 |
|---|---|
cancelAnimation(view, property, value) | 取消动画并 resetTo 指定值 |
applyImmediately(view, property, value) | 等同于 cancelAnimation(语义更清晰) |
isAnimating(view, property) | 通过检查 View Tag 是否为 null 判断动画状态 |
4.4 第 4 层:视图状态管理
文件: packages/SystemUI/miuiModules/StatusBar/src/main/java/com/android/systemui/statusbar/anim/MiuiStatusBarFolmeViewState.kt
open class MiuiStatusBarFolmeViewState {
var gone = false
var hidden = false
var alpha: Float = 1f
var translationX: Float = 0f
var scaleX: Float = 1f
var scaleY: Float = 1f
var blur: Int = 0
}核心方法:
| 方法 | 逻辑 |
|---|---|
animateTo(view, properties) | 差量动画:对每个属性比较当前值与目标值,仅变化的属性启动动画,未变化的取消动画 |
applyToView(view, force) | 应用状态:force=true 直接设值;force=false 时检查是否有进行中的动画,有则更新目标值,无则直接设值 |
cancelAnimations(view) | 调用 Folme.use(view).state().cancel() 取消全部动画,并清除所有属性的 Tag |
resetToTranslationX(view, dx) | 重置 translationX 并清除对应 Tag |
force 参数设计:
force = false(锁屏、桌面场景):保留进行中的动画,仅更新目标值,保证动画连续性force = true(其他场景):强制覆盖所有属性值,跳过动画
4.5 适配器层
文件: packages/SystemUI/miuiModules/miuiutils/src/main/java/com/miui/utils/animation/AnimationListenerFolmeConverter.kt
class AnimationListenerFolmeConverter(
private val listener: Animator.AnimatorListener,
private val animator: Animator = ValueAnimator()
) : TransitionListener() {
override fun onComplete(toTag: Any?) { listener.onAnimationEnd(animator) }
override fun onCancel(toTag: Any?) { listener.onAnimationCancel(animator) }
override fun onBegin(toTag: Any?) { listener.onAnimationStart(animator) }
}用途:将传统 Android Animator.AnimatorListener 适配为 Folme 的 TransitionListener,用于从 ObjectAnimator 向 Folme 迁移的过渡期,避免大规模重写回调逻辑。
5. 通知系统动画架构
通知系统对 Folme 的使用最为深入,定义了完整的动画类型体系。
5.1 动画类型定义
文件: packages/SystemUI/miui/Notification/src-base/com/android/systemui/statusbar/notification/stack/ViewStateInjector.kt (L292-344)
MiuiNotificationFolmeAnimations 对象定义了 12 种动画类型:
| 常量 | 值 | 场景 |
|---|---|---|
FOLME_TYPE_FOR_ANIM_OBJECT | EXT+1 | 通用动画对象 |
FOLME_TYPE_ADD_REMOVE | EXT+10 | 通知添加/移除 |
FOLME_TYPE_WAKE_UP | EXT+11 | 屏幕唤醒 |
FOLME_TYPE_TO_AOD | EXT+12 | 进入 AOD 息屏显示 |
FOLME_TYPE_WAKE_UP_AOD | EXT+13 | 从 AOD 唤醒 |
FOLME_TYPE_PANEL_VISIBLE_APPEAR | EXT+14 | 面板出现 |
FOLME_TYPE_PANEL_VISIBLE_HIDDEN | EXT+15 | 面板隐藏 |
FOLME_TYPE_PANEL_EXPAND | EXT+16 | 面板展开 |
FOLME_TYPE_PANEL_SLIDE | EXT+17 | 面板滑动 |
FOLME_TYPE_TOUCH | EXT+18 | 触摸反馈 |
FOLME_TYPE_HUN_DRAG_DOWN_DISAPPEAR | EXT+19 | Heads-up 下拉消失 |
FOLME_TYPE_HUN_REPLACE_DISAPPEAR | EXT+20 | Heads-up 替换消失 |
FOLME_TYPE_HUN_ISLAND_APPEAR | EXT+21 | 灵动岛通知出现 |
EXT =
11000 + AnimationEvent.ANIMATION_TYPE_HEADS_UP_CYCLING_IN,确保不与 AOSP 原生动画类型冲突。
5.2 属性常量体系
每种动画类型都有对应的命名属性常量,用于 Folme.useValue() 的属性键:
// 通知添加/移除
FOLME_PROPERTY_ADD_REMOVE_SCALE_X / SCALE_Y / TRANS_ALPHA / TRANS_Y
// AOD 唤醒
FOLME_PROPERTY_WAKE_UP_AOD_TRANS_Y / SCALE_X / SCALE_Y / ALPHA / ROTATION_X
// 面板展开
FOLME_PROPERTY_PANEL_OBJECT_EXPAND_SCALE / ALPHA / TRANS_X / TRANS_Y / SMALL_TRANS_Y / BIG_TRANS_Y
FOLME_PROPERTY_PANEL_OBJECT_SLIDE_TRANS_X
// 触摸反馈
FOLME_PROPERTY_TOUCH_SCALE_X / SCALE_Y / ALPHA
// Heads-up 手势
FOLME_PROPERTY_HUN_DRAG_DOWN_DISAPPEAR_SCALE_X / SCALE_Y / ALPHA
FOLME_PROPERTY_HUN_REPLACE_DISAPPEAR_SCALE_X / SCALE_Y / ALPHA / TRANS_Z
FOLME_PROPERTY_HEADSUP_APPEAR_WITH_ISLAND_ALPHA
5.3 状态管理
通知系统通过 folmeStateMap[FOLME_TYPE_XXX] 管理每种动画类型的运行状态,提供 isAnimating 属性查询:
val isAddRemoveAnimating get() = folmeStateMap[FOLME_TYPE_ADD_REMOVE]?.isAnimating ?: false
val isWakeUpAnimating get() = folmeStateMap[FOLME_TYPE_WAKE_UP]?.isAnimating ?: false
val isPanelExpandAnimating get() = folmeStateMap[FOLME_TYPE_PANEL_EXPAND]?.isAnimating ?: false
// ...6. 典型使用模式
6.1 模式一:一行触摸反馈
最简单的用法,为任何 View 添加按压回弹动画:
// QuickSetting 控件
Folme.useAt(view).touch();
// 可配置色调(tint overlay)
Folme.useAt(v).touch().setTint(0f, 0f, 0f, 0f);
// 可配置悬浮效果
Folme.useAt(view).hover().setEffect(IHoverStyle.HoverEffect.NORMAL);6.2 模式二:Kotlin 扩展 + 值动画
用于非 View 绑定的控制器级动画(如展开比例):
// 控制中心头部展开
private val animator = Folme.useValue(this).apply {
setTo(ViewProperty.TRANSLATION_X, 0)
}
// 横屏显示/隐藏
private val landShowingFolme = Folme.useValue(LAND_SHOWING_FOLME)
.setTo(ViewProperty.TRANSLATION_X, 0)6.3 模式三:多 View 批量绑定
控制中心头部一次性绑定十余个 View 的 Folme 实例,统一管理动画:
// CombinedHeaderController.kt
internal val notificationHorizontalTimeFolme = Folme.useAt(notificationHorizontalTime)
internal val notificationBigTimeFolme = Folme.useAt(notificationBigTime)
internal val controlCenterDateViewFolme = Folme.useAt(controlCenterDateView)
internal val controlCenterStatusBarFolme = Folme.useAt(controlCenterStatusBar)
// ... 共 12 个 View
private val animator = Folme.useAt(headerView).state()6.4 模式四:状态驱动的属性动画(StatusBar)
通过 MiuiStatusBarFolmeViewState + FolmeProperties 实现声明式状态过渡:
// 定义目标状态
val targetState = MiuiStatusBarFolmeViewState()
targetState.alpha = 0f
targetState.scaleX = 0.8f
targetState.scaleY = 0.8f
// 声明动画属性
val properties = FolmeProperties()
.animateAlpha(callback)
.animateScale()
.apply { config = AnimConfig().setEase(springEase) }
// 执行差量动画
targetState.animateTo(iconView, properties)6.5 模式五:外屏(Flip)状态动画
使用 AnimState + AnimConfig 定义显示/隐藏状态,通过 to() 切换:
// DecorWindowController.java
Folme.useAt(mWindowRootView).state().to(mShowAnimState); // 显示
Folme.useAt(mWindowRootView).state().to(mDismissAnimState, mDismissAnimConfig); // 隐藏(带回调)
Folme.useAt(mWindowRootView).state().setTo(mShowAnimState); // 立即显示(无动画)6.6 模式六:传统 Animator 迁移
对于已有 Animator.AnimatorListener 的老代码,使用适配器无缝迁移:
val folmeListener = AnimationListenerFolmeConverter(existingAnimatorListener)
val config = AnimConfig().addListeners(folmeListener)
Folme.use(view).state().to(ViewProperty.ALPHA, 1f, config)7. 模块覆盖分布
| 模块 | 使用场景 | 使用密度 |
|---|---|---|
| StatusBar | 图标动画、电池动画、隐私指示器、灵动岛 | 高(封装层所在模块) |
| Notification | 添加/移除动画、面板展开/滑动、AOD 过渡、触摸反馈、Heads-up | 极高(12 种动画类型) |
| ControlCenter/QuickSetting | 头部展开、磁贴触摸、详情页动画、折叠屏头部 | 高(批量 View 绑定) |
| Keyguard | 时钟动画、图案/PIN 输入、解锁动画 | 中 |
| Flip | 外屏通知窗口动画、宠物/涂鸦互动、模板动画 | 中 |
| MiuiCharge | 充电动画视图 | 低 |
| Base/miuiutils | 工具类和扩展(全局基础设施) | — |
8. 架构全景
┌────────────────────────────────────────────────────────────────┐
│ 业务层(149+ 源文件) │
│ │
│ Keyguard │ Notification │ ControlCenter │ StatusBar │
│ Flip │ MiuiCharge │ QuickSetting │ ... │
├────────────────────────────────────────────────────────────────┤
│ 第 4 层:MiuiStatusBarFolmeViewState │
│ 视图状态描述 → 差量动画 / 状态应用 │
├────────────────────────────────────────────────────────────────┤
│ 第 3 层:FolmePropertyAnimator + FolmeProperties │
│ 属性级动画调度、去重、生命周期管理 │
│ FolmeAnimatableProperty (ALPHA/SCALE/TRANSLATION/BLUR)│
├────────────────────────────────────────────────────────────────┤
│ 第 2 层:FolmeUtils (instantTo / useValue 增强) │
│ AnimationListenerFolmeConverter (迁移适配) │
├────────────────────────────────────────────────────────────────┤
│ 第 1 层:Folme.kt (Kotlin 扩展属性 / FolmeObject 委托) │
├────────────────────────────────────────────────────────────────┤
│ miuix.folme (4.0.0-alpha03, 399KB AAR) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Folme (入口) │ IFolme │ IStateStyle │ AnimConfig │ │
│ │ ViewProperty │ FloatProperty │ TransitionListener │ │
│ │ FolmeEase │ AnimState │ ITouchStyle │ IHoverStyle │ │
│ └──────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────┤
│ miuix.animation (4.0.0-alpha03) │
│ 物理弹簧模型 / 属性插值引擎 │
└────────────────────────────────────────────────────────────────┘
9. 与 Android 原生动画的关键差异
| 维度 | Android Animator | Folme |
|---|---|---|
| 驱动模型 | 时间曲线(Interpolator + duration) | 物理弹簧(damping + stiffness)或时间曲线 |
| 中断行为 | 需手动 cancel + 启动新动画 | 直接调用 to() 新目标值,自动平滑衔接 |
| 状态管理 | 无内置状态,需外部追踪 | 内置状态机,setTo/resetTo/to 语义清晰 |
| 触摸反馈 | 需手动实现 OnTouchListener + 动画 | Folme.useAt(view).touch() 一行搞定 |
| 属性扩展 | Property<T, V> | FloatProperty<T>,可自定义(如 BLUR) |
| 生命周期 | 绑定 View 需手动管理 | Folme.use(view) 自动绑定,随 View 回收 |
核心优势:Folme 基于物理弹簧模型的动画可以在任意时刻被新目标值平滑中断,无需手动处理取消和衔接逻辑。这在 SystemUI 这种高频状态切换的场景中尤为关键。
10. 注意事项与潜在风险
- 版本锁定:当前使用
4.0.0-alpha03alpha 版本,API 可能存在不稳定性 - 单一依赖风险:全项目完全依赖 Folme,一旦该库有 bug,影响面极广
- View Tag 冲突:
FolmePropertyAnimator使用View.setTag(R.id.xxx)追踪动画状态,需确保 tag ID 不与其他模块冲突 - 内存管理:
Folme.use(view)会在 View 上创建并持有IFolme实例,大量 View 同时持有可能增加内存压力 - 调试困难:物理弹簧动画没有固定时长,难以在 Systrace/Perfetto 中精确分析时间轴
附录 A:关键文件索引
| 文件 | 路径 | 职责 |
|---|---|---|
| AAR 制品 | packages/SystemUI/miuix_library/prebuilts-alpha/miuix/folme/folme/4.0.0-alpha03/ | Folme 预编译库 |
| Android.bp | packages/SystemUI/miuix_library/prebuilts-alpha/Android.bp (L52-75) | AOSP 构建依赖声明 |
| Folme.kt | packages/SystemUI/miuiModules/miuiutils/.../animation/Folme.kt | Kotlin 扩展 + FolmeObject 委托 |
| FolmeUtils.kt | packages/SystemUI/miuiModules/Base/.../util/FolmeUtils.kt | instantTo + useValue 增强 |
| FolmeAnimatableProperty.kt | packages/SystemUI/miuiModules/StatusBar/.../anim/FolmeAnimatableProperty.kt | 可动画属性接口 + 预定义常量 |
| FolmePropertyAnimator.kt | packages/SystemUI/miuiModules/StatusBar/.../anim/FolmePropertyAnimator.kt | 属性动画调度器(核心) |
| FolmeProperties.kt | packages/SystemUI/miuiModules/StatusBar/.../anim/FolmeProperties.kt | 动画声明 Builder |
| MiuiStatusBarFolmeViewState.kt | packages/SystemUI/miuiModules/StatusBar/.../anim/MiuiStatusBarFolmeViewState.kt | 视图状态管理 |
| AnimationListenerFolmeConverter.kt | packages/SystemUI/miuiModules/miuiutils/.../animation/AnimationListenerFolmeConverter.kt | Animator 兼容适配器 |
| ViewStateInjector.kt | packages/SystemUI/miui/Notification/.../stack/ViewStateInjector.kt (L292-344) | 通知动画类型体系定义 |