Controller 是一种管理子部件、重写或自定义其事件处理或更新行为的类型。Controller控制器只能处理事件和更新,不能影响布局和绘制。控制器是一种方便; 它可以做的任何事情也可以通过创建一个拥有子控件的自定义 Widget 来完成。但是,这有点麻烦,特别是当您只想拦截或修改一个或两个事件时。Controller 上的方法与 Widget 上的方法相同,只是它们也被传递给控制器的子方法。控制器负责根据需要显式地将调用转发到子级。Controller 与 ControllerHost 一起使用,后者管理它与其子节点之间的关系; 尽管通常您会使用 WidgetExt: : Controller 方法,而不是直接实例化主机。
Controller有3个需要实现的方法
代码语言:javascript复制pub fn event(
&mut self,
child: &mut W,
ctx: &mut EventCtx<'_, '_>,
event: &Event,
data: &mut T,
env: &Env
)
pub fn lifecycle(
&mut self,
child: &mut W,
ctx: &mut LifeCycleCtx<'_, '_>,
event: &LifeCycle,
data: &T,
env: &Env
)
// 更新
pub fn update(
&mut self,
child: &mut W,
ctx: &mut UpdateCtx<'_, '_>,
old_data: &T,
data: &T,
env: &Env
)
1、我们先编写controller控制器 来看看
代码语言:javascript复制struct TakeFocus;
impl <T, W: Widget<T>> Controller<T, W> for TakeFocus {
//处理事件
/*
child:小部件
EventCtx:事件etc
Event:事件
data:数据
*/
fn event(&mut self, child: &mut W, ctx: &mut EventCtx, event: &Event, data: &mut T, env: &Env) {
//当窗口第一次实例化的时候接收到WindowConnectioned
if let Event::WindowConnected = event {
//让小部件获得焦点
ctx.request_focus();
}
child.event(ctx, event, data, env)
}
}
2、编写我们的ui,创建textBox并且让textBox使用controller控制器
代码语言:rust复制#[derive(Data,Lens,Clone)]
struct AppState{
text:String
}
fn builder_ui() -> impl Widget<AppState>{
Flex::row()
//给输入框添加controller控制器
.with_child(TextBox::multiline().controller(TakeFocus).lens(AppState::text))
}
// 运行起来;
fn main() {
let win = WindowDesc::new(builder_ui()).window_size((200.,200.));
let _app = AppLauncher::with_window(win).launch(AppState{text:"".to_string()});
}