前言
文档参考:https://docs.rs/xilem/latest/xilem/view/fn.split.html
版本:Xilem 0.4
一、split基础概念
split 是双面板可拖拽分割布局原语,容器只能容纳两个子视图,中间有可拖动分割条,鼠标拖动分割条可以动态修改两块面板所占区域大小。
适用场景:
编辑器左右分栏、上下分栏、侧边可缩放面板。
对比其它布局
- flex:一维排列,不可拖拽调整尺寸
- split:固定两个子面板,自带可拖拽分割条,支持水平分割、垂直分割
引入
usexilem::view::{split,label,sized_box};usexilem::Axis;二、函数签名
pubfnsplit<State,Action,ChildA,ChildB>(child1:ChildA,child2:ChildB,)->Split<ChildA,ChildB,State,Action>whereChildA:WidgetView<State,Action>,ChildB:WidgetView<State,Action>,- 仅接收两个子视图,第一个参数面板A,第二个参数面板B;不支持3个及以上面板直接放入split。
- 返回Split对象,通过链式方法修改分割方向、初始分割位置。
三、核心链式修饰方法
1. .split_axis(Axis) 设置分割方向
- Axis::Horizontal :垂直分割条,左右两个面板,拖动分割条改变左右宽度
- Axis::Vertical :水平分割条,上下两个面板,拖动分割条改变上下高度
默认值: Axis::Horizontal ,默认左右分割。
2. .split_point(f64) 设置初始分割比例
取值范围 0.0 ~ 1.0 。
- 0.25 :第一个子视图占整体25%,第二个占75%
- 0.5 :两边各占一半,50% / 50%
- 0.7 :第一个占70%,第二个占30%
基础示例,左右分割,初始比例25%/75%
split(label("左侧面板"),label("右侧面板")).split_axis(Axis::Horizontal).split_point(0.25)上下分割示例:
split(label("上方面板"),label("下方面板")).split_axis(Axis::Vertical).split_point(0.5)四、split与sized_box配合
split本身需要父容器提供可用空间。如果子面板内想要背景色、内边距,需要子视图外层包裹 sized_box 。
split(sized_box(label("左面板")).expand().background(palette::css::LIGHT_BLUE),sized_box(label("右面板")).expand().background(palette::css::LIGHT_GRAY)).split_point(0.4)子面板内部建议使用 .expand() ,让子视图填满split分配给它的区域。
重要限制:
split只能放恰好两个子view;想要实现三块分割面板,需要split嵌套split。
嵌套split实现三栏布局
外层左右split,右侧面板内部再做上下split。
split(sized_box(label("左栏")).expand().background(palette::css::LIGHT_BLUE),split(sized_box(label("右上")).expand().background(palette::css::LIGHT_GREEN),sized_box(label("右下")).expand().background(palette::css::LIGHT_PINK)).split_axis(Axis::Vertical).split_point(0.5)).split_axis(Axis::Horizontal).split_point(0.3)五、完整可运行示例
Cargo.toml
[package] name = "xilem_lesson27" version = "0.1.0" edition = "2021" [dependencies] xilem = "0.4.0" winit = "0.30"src/main.rs
usexilem::palette;usexilem::winit::error::EventLoopError;usexilem::view::{split,sized_box,label};usexilem::{Axis,EventLoop,WidgetView,WindowOptions,Xilem};#[derive(Default)]structAppState;fnapp_logic(_state:&mutAppState)->implWidgetView<AppState>+use<>{// 左右分割,初始比例4:6split(sized_box(label("左侧面板\n拖动中间分割条调整大小")).expand().background(palette::css::ALICE_BLUE),sized_box(label("右侧面板")).expand().background(palette::css::LIGHT_GRAY)).split_axis(Axis::Horizontal).split_point(0.4)}fnmain()->Result<(),EventLoopError>{letapp=Xilem::new_simple(AppState::default(),app_logic);app.run(EventLoop::with_user_event(),WindowOptions::default())}运行效果:
鼠标放在中间分割条上,按住鼠标左右拖动,两块面板尺寸会动态变化。
六、高频踩坑清单
- split只能接收恰好两个子视图,不能传入元组、不能直接放3个及以上view;多面板只能嵌套split。
- .split_point() 参数范围是0.0‑1.0的比例值,不是像素,不是px。
- 子视图不会自动填满split分配的面板区域,子view内部需要 sized_box(…).expand() 。
- split分割方向 Axis::Horizontal =左右分(垂直分割条); Axis::Vertical =上下分(水平分割条),容易记反。
- split的拖拽状态不会保存到AppState,拖动改变的布局是临时UI状态,框架内部维护,业务state拿不到分割点数值。重启窗口会恢复 .split_point() 设置的初始比例。
- split没有直接设置分割条颜色、粗细的公开View层API,分割条样式由底层Masonry控制。
- split外层父容器必须给它分配足够空间;放在没有约束的容器内,split可能无法正常渲染。
七、课后练习题
仅使用本课split,搭配sized_box、label;不使用未收录API。
练习1(基础)
写一个上下分割的split布局:
- 上方文本: 上半区 ,背景浅蓝;
- 下方文本: 下半区 ,背景浅灰;
- 初始分割比例0.3,上方占30%,下方占70%。
参考答案
split(sized_box(label("上半区")).expand().background(palette::css::LIGHT_BLUE),sized_box(label("下半区")).expand().background(palette::css::LIGHT_GRAY)).split_axis(Axis::Vertical).split_point(0.3)练习2(进阶)
嵌套split实现布局:
最外层:上下分割(上:下 = 0.2 : 0.8);
外层的下方面板,内部再做左右分割(左:右 =0.3 :0.7)。
###参考答案
split(sized_box(label("顶部标题区")).expand().background(palette::css::LIGHT_GRAY),split(sized_box(label("左侧侧边栏")).expand().background(palette::css::LIGHT_BLUE),sized_box(label("主内容区")).expand().background(palette::css::WHITE)).split_axis(Axis::Horizontal).split_point(0.3)).split_axis(Axis::Vertical).split_point(0.2)练习3(拓展)
flex_col外层,第一行放label标题;第二行放置练习1的上下分割split。
参考答案
flex_col((sized_box(label("Split演示页面")).expand_width().background(palette::css::ALICE_BLUE),split(sized_box(label("上半区")).expand().background(palette::css::LIGHT_BLUE),sized_box(label("下半区")).expand().background(palette::css::LIGHT_GRAY)).split_axis(Axis::Vertical).split_point(0.3)))八、知识点总结
- split 是双面板可拖拽分割布局,只接收两个子view,自带拖拽分割条。
- .split_axis(Axis) 控制分割方向:Horizontal左右分割;Vertical上下分割。
- .split_point(0.0~1.0) 设置初始占比,是比例,不是像素。
- 子面板需要 sized_box(…).expand() 填满分配到的面板空间;背景、padding在子sized_box设置。
- 多于两个面板,必须嵌套split。
- 拖拽调整的分割位置属于内部临时状态,不会保存到业务AppState,重启回到初始split_point。
- split依赖父容器提供布局空间,常与flex_col、sized_box组合使用。