由于一直找不到自己喜欢的表盘,所以研究了一下小米手环表盘开发。
本文主要总结使用 EasyFace 制作小米手环表盘时遇到的一些问题和解决方法,方便自己以后查阅。
内容参考了米坛社区 的相关教程,并加入了一些自己的实践经验。
EasyFace
EasyFace 是一个用于制作小米生态设备表盘的可视化工具。
项目地址:https://github.com/m0tral/EasyFace
EasyFace 汉化版:
下载完成后解压,可以看到类似以下文件:
需要使用管理员权限运行 EasyFace.exe。
可以在文件属性中设置:
右键 EasyFace.exe
→ 属性
→ 兼容性
→ 以管理员身份运行此程序
打开 EasyFace 后,点击工具栏中的新建项目按钮:
根据提示填写项目信息,确定后即可创建工程。
解包已有表盘
如果想参考其他人的表盘,可以使用 UnpackMiColorFace 对已有的 .bin 表盘文件进行解包。
项目地址:https://github.com/m0tral/UnpackMiColorFace
下载完成后,将需要解包的 .bin 文件直接拖动到 UnpackMiColorFace 上即可。
解包后的目录通常可以得到表盘中的图片等资源。
不过需要注意:
解包并不等于完整还原 EasyFace 工程。
部分表盘在解包后可能出现:
- 控件位置错位
- 部分组件丢失
- 点击跳转信息丢失
- 可编辑信息丢失
- 动画信息不完整
- 部分配置无法还原
因此解包得到的文件通常只能作为参考素材和逆向分析的基础,不能保证可以直接重新导入 EasyFace 使用。
如果只是想提取图片素材,解包通常已经足够;如果想完整修改表盘,则可能需要自己重新搭建控件。
制作表盘
这里不重复介绍 EasyFace 的所有基础功能,只记录一些我实际制作过程中比较重要的内容。
如果是第一次使用 EasyFace,建议先阅读米坛社区的完整教程:
【0821】EasyFace详细使用教程(零基础,适合7Pro、8、8Pro)
可跳转组件
可以通过特定的图片控件名称,让用户点击表盘上的图片区域后直接打开对应功能。
将图片控件名称设置为:
btn_[XXXXX]
其中 XXXXX 替换为对应的组件 ID。
目前常用的组件 ID:
| ID | 功能 |
|---|---|
steps |
步数 |
calories |
卡路里 |
standing |
站立 |
moving |
活动 |
hrm |
心率 |
spo2 |
血氧 |
stress |
压力 |
sleep |
睡眠 |
weather |
天气 |
alarm |
闹钟 |
timer |
计时器 |
stopwatch |
秒表 |
cards |
卡片 |
music |
音乐 |
compass |
指南针 |
calendar |
日历 |
flashlight |
手电筒 |
photo |
拍照 |
findphone |
查找手机 |
settings |
设置 |
wechat |
微信 |
alipay |
支付宝 |
例如制作一个点击后打开心率的区域:
btn_[hrm]
点击该图片区域后即可打开对应功能。
另外,跳转区域必需使用图片控件,图片列表、通用数字显示、时钟等控件不能直接作为跳转组件使用。
如果只是想增加一个透明的点击区域,可以制作一张透明图片,然后将图片控件命名为:
btn_[hrm]
这样就可以让这个区域作为心率的点击区域。
缓亮
在 EasyFace 工程目录下创建:
app/
└── _lua/
然后在 _lua 文件夹中创建:
SmoothlyLight.lua
内容如下:
local lvgl = require("lvgl")
local img_index = 255
scr = lvgl.Object(nil, {
w = lvgl.HOR_RES(),
h = lvgl.VER_RES(),
bg_color = 0,
bg_opa = 0,
border_width = 0,
pad_all = 0
})
orderedTimer = lvgl.Timer({
period = 5,
cb = function(t)
scr:set({
bg_opa = img_index
})
img_index = img_index - 50
if img_index < 6 then
orderedTimer:pause()
scr:add_flag(lvgl.FLAG.HIDDEN)
end
end,
})
function ScreenStateChangedCB(pre, now, reason)
if pre ~= "ON" and now == "ON" then
img_index = 255
scr:clear_flag(lvgl.FLAG.HIDDEN)
orderedTimer:resume()
end
end
return
修改下面的代码可以调整缓亮速度:
period = 5
period 表示定时器执行的间隔,单位为毫秒。
img_index = img_index - 50
img_index 控制每次透明度降低多少。
实际动画速度由这两个参数共同决定。
然后在 EasyFace 中创建一个普通容器。
容器需要设置:
X = 0
Y = 0
大小覆盖整个表盘。
以小米手环 9 Pro 为例:
X = 0
Y = 0
W = 336
H = 480
然后将容器名称设置为:
app__lua%2FSmoothlyLight.lua
这里需要注意,只有在该控件之下的控件才能有缓亮效果,同时被覆盖区域的跳转控件会失效,可以使用透明图片作为跳转控件,置于缓亮控件之上来解决。
在easyface中添加好透明的点击控件之后,使用文本编辑器修改为如下结构:
AOD 表盘
如果需要制作 AOD(息屏显示)表盘,可以直接在工程目录下新建一个名为AOD的表盘工程。
AOD 的制作方式与主表盘基本一致。
例如:
主工程/
├── images/
├── xxx.fprj
└── AOD/
└── AOD.fprj
动画
点击“工具箱-基础控件-图片列表”,画一个合适的大小,之后将名字命名为anim_[xx@yy]
xx:运行次数, 0 - 无限
yy:时间帧, 单位:毫秒(ms),数字越小图片动的越快
多样式表盘
可以通过多个工程文件制作多样式表盘。
首先将主工程文件复制一份。
复制后命名为:
1_name.fprj
继续增加其他样式时,可以使用:
2_name.fprj
3_name.fprj
4_name.fprj
分别打开这些工程修改对应的表盘样式。
完成后回到主工程进行编译。
多个工程之间的图片素材可以共用,因此不需要为每个样式重复保存一份图片。
注意事项
EasyFace 编译器不会正常识别
images文件夹中的子文件夹。同一组图片的分辨率需要一致
通用数字显示需要填写负号,通常可以直接选择数字
0作为负号图片,对于温度等可能出现负数的数据,则需要准备真正的-图片,并将其设置为负号。EasyFace 的控件存在明显的前后层级关系,如果一个控件被其他控件完全覆盖,就可能看起来像是“没有显示”。
编译好的表盘文件在
output目录下,使用Astrobox将.face文件刷入设备,或将后缀改为.bin使用米环自定义工具刷入。
参考资料
https://github.com/m0tral/EasyFace
https://github.com/m0tral/EasyFace/wiki/HomeCN
https://www.bandbbs.cn/threads/10010/
https://www.bandbbs.cn/threads/21776
https://www.bandbbs.cn/threads/7188/
本文主要作为个人学习和开发笔记,部分功能来自社区教程及实际测试。由于 EasyFace、设备固件和表盘格式仍可能发生变化,部分功能在不同设备或版本上可能存在差异。
最后分享一下我做的表盘:
基于官方表盘复杂多功能修改,修改了配色、添加缓亮效果、全部组件可点击。






