前言
参考官方文档:https://docs.rs/xilem/latest/xilem/view/fn.progress_bar.html
版本:Xilem 0.4
一、progress_bar 基础概念
progress_bar 是 Xilem0.4 内置原生进度条组件,用于展示任务完成进度、加载状态。
它支持两种核心模式:
1. 确定进度模式:已知完成百分比(0%–100%)
2. 不确定加载模式:未知时长的动态流动加载动画
进度条是原生控件,无需自定义绘制、无需图片资源,开箱即用。
二、函数签名
pubfnprogress_bar(progress:Option<f64>)->ProgressBar参数详解
progress 为` 类型,只有两种合法状态:
1. Some(数值) :确定进度模式
数值范围标准 0.0 ~ 1.0 ,对应 0%–100%
超出范围会自动归一化取模,不会崩溃
2. None :不确定加载模式
显示持续滚动的 loading 动画
三、两种运行模式说明
1. 确定进度模式
传入 Some(0.0) 空进度, Some(1.0) 满进度,中间数值按比例填充。
适合:文件下载、任务处理、安装进度、表单完成度。
2. 不确定加载模式
传入 None ,无固定百分比,持续动画流动。
适合:网络请求、等待响应、未知耗时加载。
四、最简基础用法
// 50% 固定进度progress_bar(Some(0.5))// 无限加载动画progress_bar(None)五、完整可运行示例(可交互)
Cargo.toml
[package] name = "xilem_lesson31" version = "0.1.0" edition = "2021" [dependencies] xilem = "0.4.0" winit = "0.30"src/main.rs
usexilem::winit::error::EventLoopError;usexilem::view::{progress_bar,text_button,checkbox,label};usexilem::{EventLoop,WidgetView,WindowOptions,Xilem};#[derive(Default)]structAppState{<f64>,}fnapp_logic(state:&mutAppState)->impl<AppState><>{flex_col((label("ProgressBar 进度条演示"),progress_bar(state.progress),checkbox("开启未知加载动画",state.progress.is_none(),|s:&mutAppState,checked|{ifchecked{s.progress=None;}else{s.progress=Some(0.2);}}),text_button("进度 +10%",|s:&mutAppState|{ifletSome(p)=&muts.progress{*p=(*p+0.1).rem_euclid(1.0);}else{s.progress=Some(0.0);}}),))}fnmain()->Result<(),EventLoopError>{letapp=Xilem::new_simple(AppState{progress:Some(0.2)},app_logic);app.run(EventLoop::with_user_event(),WindowOptions::default())}六、高频踩坑清单
- 进度值只识别 0.0~1.0 ,不是 0~100,不要直接填百分比数字。
- 开启动画必须传 None ,没有单独的 indeterminate() 链式方法。
- 进度条无公开自定义样式API,无法直接改颜色、高度、圆角(0.4版本底层固化)。
- 修改进度必须修改 state,不能写死常量做动态更新。
- rem_euclid(1.0) 可以让进度超过1.0后自动归零,形成循环效果。
七、课后练习题 + 标准答案 + 逐行解读
练习1(基础)
需求:
创建界面,固定展示 70% 静态进度条。
参考答案
flex_col((label("静态进度 70%"),progress_bar(Some(0.7)),))详细解读
- Some(0.7) 代表进度 70%,属于确定进度模式。
- 直接传入常量,页面固定显示70%填充状态,无动画、无交互。
- 无需状态结构体,适合展示固定完成度场景。
练习2(进阶)
需求:
动态进度条 + 实时百分比文字展示,点击按钮递增进度。
参考答案
#[derive(Default)]structAppState{val:f64}fnapp_logic(state:&mutAppState)->implWidget<AppState>+<>{flex_col((label(format!("当前进度:{:.0}%",state.val*100.0)),progress_bar(Some(state.val)),text_button("增加10%进度",|s:&mutAppState|{s.val=(s.val+0.1).min(1.0);})))}详细解读
- 单独用 f64 存储进度数值,更适合纯确定进度场景。
- state.val * 100.0 将 0–1 数值转为百分比文字展示,直观可读。
- progress_bar(Some(state.val)) 绑定动态状态,状态改变自动刷新进度。
- .min(1.0) 限制进度最大 100%,防止溢出。
- 点击按钮每次递增 0.1,实现平滑进度上涨效果。
练习3(拓展)
需求:
实现双模式切换
- 勾选复选框:进入未知 loading 动画
- 取消勾选:恢复可递增进度条
参考答案
#[derive(Default)]structAppState{<f64>}fnapp_logic(state:&mutAppState)->impl<AppState><>{flex_col((progress_bar(state.progress),checkbox("未知加载模式",state.progress.is_none(),|s:&mutAppState,ck|{s.progress=ifck{None}else{Some(0.0)};}),text_button("进度 +0.1",|s:&mutAppState|{ifletSome(p)=&muts.progress{*p=(*p+0.1).min(1.0);}})))}详细解读
- 使用 Option 同时兼容两种模式,是官方推荐标准写法。
- state.progress.is_none() 自动同步复选框勾选状态。
- 勾选赋值 None → 开启无限流动画。
- 取消勾选赋值 Some(0.0) → 重置为0%正常进度条。
- 按钮做判断:只有确定进度模式时,才允许递增进度,避免动画模式下报错。
思考题答案
问题:为什么 progress_bar` 而不是单独布尔值?
标准答案解读
- 一个类型同时承载两种UI状态:固定进度 / 未知动画,极简状态管理。
- 如果用布尔值+数值双字段,会产生状态不一致、冗余代码。
- 官方设计语义: Some=有进度数值 、 None=无具体进度 ,符合加载业务逻辑。
八、知识点总结
- progress_bar 仅有唯一入参 Option ,控制两种核心展示形态。
- Some(0.0~1.0) 为固定进度条,None 为无限加载动画条。
- 动态进度必须绑定 AppState,常量只能做静态展示。
- 0.4 版本无自定义样式API,样式由底层统一渲染。
- 可通过 min / rem_euclid 控制进度边界,实现封顶或循环效果。
- Option 枚举设计,是 Xilem 典型的单状态双UI精简范式。