15 - 在视图之间切换
在上一步中,我们创建了图片浏览器(ImageBrowser),这是实现图片网格与幻灯片之间切换功能的一部分。
回顾我们的计划:
- 首先,创建一个带有单个按钮的菜单栏(MenuBar)。
- 接着,创建一个图片浏览器(ImageBrowser),它由一个菜单栏加一个图片网格(ImageGrid)组成。
- 最后,使用 PageFlip 在图片浏览器和幻灯片(Slideshow)之间切换。
这一步,我们将使用 PageFlip 实现图片浏览器与幻灯片之间的视图切换。
注意:如果你不想自己敲代码,可以在这里找到本步骤的所有代码:https://github.com/makepad/image_viewer/tree/main/step_15
你将学到的内容
在这一步中,你将学习:
- 如何使用 PageFlip 在不同视图之间进行切换。
更新 App
我们先从更新 App 的定义开始,使其使用 PageFlip。
PageFlip 是一个容器,用于包含多个组件(widget),每次只显示其中一个。容器中的每个组件称为一个页面(page),当前显示的那个页面被称为活动页面(active page)。每个页面都有一个名称,可以通过这个名称来设置当前活动页面。
在 app.rs
的 live design
块中,添加以下代码:
1App = {{App}} {
2 placeholder: (PLACEHOLDER),
3
4 ui: <Root> {
5 <Window> {
6 body = <View> {
7 page_flip = <PageFlip> {
8 active_page: image_browser,
9
10 image_browser = <ImageBrowser> {}
11 slideshow = <Slideshow> {}
12 }
13 }
14 }
15 }
16 }
这段代码定义了一个包含两个页面的 PageFlip:
image_browser
:包含一个 ImageBrowser。
slideshow
:包含一个 Slideshow。
当前活动页面被设置为 image_browser
。
处理事件
接下来,我们将更新事件处理代码,以响应以下用户事件:
- 当用户点击图像浏览器中的幻灯片按钮时,我们应切换到幻灯片视图(Slideshow)。
- 当用户在幻灯片视图中按下 Escape 键时,我们应切换回图像浏览器(ImageBrowser)。
在 app.rs
中,替换 App
结构体上 MatchEvent
trait 的 handle_actions
方法定义,使用如下代码:
1fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) {
2 if self.ui.button(id!(slideshow_button)).clicked(&actions) {
3 self.ui
4 .page_flip(id!(page_flip))
5 .set_active_page(cx, live_id!(slideshow));
6 self.ui.view(id!(slideshow.overlay)).set_key_focus(cx);
7 }
8
9 if self.ui.button(id!(navigate_left)).clicked(&actions) {
10 self.navigate_left(cx);
11 }
12 if self.ui.button(id!(navigate_right)).clicked(&actions) {
13 self.navigate_right(cx);
14 }
15
16 if let Some(event) =
17 self.ui.view(id!(slideshow.overlay)).key_down(&actions)
18 {
19 match event.key_code {
20 KeyCode::Escape => self
21 .ui
22 .page_flip(id!(page_flip))
23 .set_active_page(cx, live_id!(image_browser)),
24 KeyCode::ArrowLeft => self.navigate_left(cx),
25 KeyCode::ArrowRight => self.navigate_right(cx),
26 _ => {}
27 }
28 }
29 }
这段代码和之前的几乎一样,只是我们添加了一些新的事件处理逻辑。下面我们详细讲解新加的部分。
以下代码:
1if self.ui.button(id!(slideshow_button)).clicked(&actions) {
2 self.ui
3 .page_flip(id!(page_flip))
4 .set_active_page(cx, live_id!(slideshow));
5 self.ui.view(id!(slideshow.overlay)).set_key_focus(cx);
6 }
检查幻灯片按钮是否被点击。如果是,就将翻页组件的活动页面切换到幻灯片页,并确保幻灯片覆盖层拥有键盘焦点。
以下代码:
1KeyCode::Escape => self
2 .ui
3 .page_flip(id!(page_flip))
4 .set_active_page(cx, live_id!(image_browser)),
检查当幻灯片覆盖层拥有键盘焦点时是否按下了 Esc 键。如果是,就将翻页组件的活动页面切换回图片浏览器。
检查目前的进度
让我们检查一下目前的进度。
确保你在你的包目录下,然后运行:
如果一切正常,你应该会看到和之前一样的图片网格,上方带有一个“幻灯片”按钮:

不过这次,点击幻灯片按钮应该会切换到幻灯片视图:

按下 Escape 键时,应该会切换回图片网格视图:

下一步
现在我们已经能够在图片网格和幻灯片之间切换了。接下来的几个步骤中,我们将添加图片过滤的功能。