焦点 Builder

这一页只介绍用于配置焦点表的 builder 方法。焦点机制的整体说明见 焦点机制,运行时通过 ViewId 操控焦点的 API 见 ViewId

实际公开的 trait 是:

pub trait FocusIndexBuilder {
    fn focus_scope(self, focus_scope: u32) -> Self;
    fn focus_index(self, focus_index: u32) -> Self;
}

focus_index

focus_index 把控件加入焦点表,并设置它在 Tab 顺序里的排序值。

use flor::view::builder::{EventBuilder, FocusIndexBuilder};
use flor_lys::label::label;

let name = label("名称")
    .focus_index(0)
    .on_focus(|_, virtual_index| {
        println!("focus virtual index: {virtual_index}");
    });

let confirm = label("确认").focus_index(1);

0 是合法排序值,不能把它理解成取消焦点。数字越小,越先被 Tab 访问。同一个排序值也能工作,最终排序还会包含 ViewId 和虚拟焦点序号;不过给同一组控件使用清晰递增的值更容易维护。

不写 focus_index 就是不加入焦点表。这样的控件不会被 Tab 选中,也不会成为控件级 on_key_* 的焦点目标。

focus_scope

focus_scope 给当前控件及其子树提供一个排序偏移。它适合把页面拆成几个区域,让每个区域内部从 0 开始编号。

use flor::view::builder::FocusIndexBuilder;
use flor::views;
use flor_lys::div::div;
use flor_lys::label::label;

let toolbar = div(views![
    label("工具 1").focus_index(0),
    label("工具 2").focus_index(1),
])
.focus_scope(100);

let content = div(views![
    label("内容 1").focus_index(0),
    label("内容 2").focus_index(1),
])
.focus_scope(200);

上面的最终排序值是:

控件局部写法最终排序值
工具 1100 + 0100
工具 2100 + 1101
内容 1200 + 0200
内容 2200 + 1201

focus_scope 可以嵌套,父级偏移会继续累加给子树。

注意:builder 的 focus_scope(u32) 只影响排序,不限制 Tab 的运行时范围。弹出层、Modal 这类焦点隔离场景使用 ViewId::push_focus_scope()ViewId::pop_focus_scope(),机制说明见 焦点机制