跳到主要内容

7 篇博文 含有标签「release」

查看所有标签

导航与路由

· 阅读需 7 分钟
Feodor Fitsner
Flet 创始人和开发者

Flet 0.1.42 已发布,带来了导航和路由功能!

导航和路由是单页应用程序(SPA)的一个重要功能,它允许将应用程序用户界面组织成虚拟页面(视图),并在它们之间“导航”,同时应用程序的URL反映了当前的应用状态。

对于移动应用,导航和路由还可以作为深层链接到特定的应用部分。

为了在 Flet 中添加导航和路由,我们付出了更多努力 ,因为实现是基于Navigator 2.0 Flutter API的,并需要用“页面和视图”取代 Flet 的“页面”抽象。Flutter 的新导航和路由 API 有以下显著改进:

  1. 对历史堆栈的编程控制。
  2. 一种简便的方法来拦截 AppBar 中的“后退”按钮调用。
  3. 与浏览器历史的强同步。

浏览示例源代码

页面路由

页面路由是应用程序URL中 # 符号之后的部分:

如果用户未在应用程序URL中设置默认应用程序路由,则默认为 /。所有路由都以 / 开头,例如 /store, /authors/1/books/2

可以通过读取 page.route 属性获取应用程序路由,例如:

import flet as ft

def main(page: ft.Page):
page.add(ft.Text(f"Initial route: {page.route}"))

ft.app(target=main, view=ft.AppView.WEB_BROWSER)

获取应用程序URL,打开一个新的浏览器标签页,粘贴URL,修改 # 后的部分为 /test,然后按回车。你应该会看到“Initial route: /test”。

每次URL中的路由发生变化(通过编辑URL或使用浏览器历史中的后退/前进按钮),Flet 都会调用 page.on_route_change 事件处理程序:

import flet as ft

def main(page: ft.Page):
page.add(ft.Text(f"Initial route: {page.route}"))

def route_change(route):
page.add(ft.Text(f"New route: {route}"))

page.on_route_change = route_change
page.update()

ft.app(target=main, view=ft.AppView.WEB_BROWSER)

现在尝试多次更新URL哈希,然后使用后退/前进按钮!每次路由变化时,你应该会看到页面上添加了一条新消息:

可以通过更新 page.route 属性以编程方式更改路由:

import flet as ft

def main(page: ft.Page):
page.add(ft.Text(f"Initial route: {page.route}"))

def route_change(route):
page.add(ft.Text(f"New route: {route}"))

def go_store(e):
page.route = "/store"
page.update()

page.on_route_change = route_change
page.add(ft.ElevatedButton("Go to Store", on_click=go_store))

ft.app(target=main, view=ft.AppView.WEB_BROWSER)

点击“Go to Store”按钮,你会看到应用程序URL已更改,并且在浏览器历史中添加了一个新项。你可以使用浏览器“后退”按钮导航到上一个路由。

页面视图

Flet 的 Page 现在不仅仅是一个单独的页面,而是一个包含叠加在一起的 View 的容器,像三明治一起:

视图的集合代表了导航器历史。Page具有 page.views 属性来访问视图集合。

列表中的最后一个视图是当前显示在页面上的视图。视图列表必须至少有一个元素(根视图)。

要模拟页面之间的过渡,请更改 page.route 并在 page.view 列表的末尾添加一个新 View

从集合中弹出最后一个视图并在 page.on_view_pop 事件处理程序中将路由更改为“上一个”路由以返回。

在路由变化时构建视图

为了构建可靠的导航,程序中必须有一个地方根据当前路由来构建视图列表。换句话说,导航历史堆栈(由视图列表表示)必须是路由的函数。

这个地方是 page.on_route_change 事件处理程序。

让我们将所有内容放在一起,完成一个允许在两个页面之间导航的完整示例:

import flet as ft

def main(page: ft.Page):
page.title = "Routes Example"

def route_change(route):
page.views.clear()
page.views.append(
ft.View(
"/",
[
ft.AppBar(title=ft.Text("Flet app"), bgcolor=ft.colors.SURFACE_VARIANT),
ft.ElevatedButton("Visit Store", on_click=lambda _: page.go("/store")),
],
)
)
if page.route == "/store":
page.views.append(
ft.View(
"/store",
[
ft.AppBar(title=ft.Text("Store"), bgcolor=ft.colors.SURFACE_VARIANT),
ft.ElevatedButton("Go Home", on_click=lambda _: page.go("/")),
],
)
)
page.update()

def view_pop(view):
page.views.pop()
top_view = page.views[-1]
page.go(top_view.route)

page.on_route_change = route_change
page.on_view_pop = view_pop
page.go(page.route)


ft.app(target=main, view=ft.AppView.WEB_BROWSER)

试试使用“Visit Store”和“Go Home”按钮在页面之间导航,使用浏览器的后退/前进按钮,手动更改URL中的路由——无论怎么做都能正常工作! :)

备注

要在页面之间“导航”,我们使用了 page.go(route) - 一个辅助方法,它更新 page.route,调用 page.on_route_change 事件处理程序来更新视图,最后调用 page.update()

注意 page.on_view_pop 事件处理程序的使用。当用户点击 AppBar 控件中的自动“后退”按钮时,它会触发。在处理程序中,我们从视图集合中删除最后一个元素,并导航到其下的视图根。

路由模板

Flet 提供 TemplateRoute——一个基于 repath 库的实用类,它允许匹配类似于 ExpressJS 的路由并解析其参数,例如 /account/:account_id/orders/:order_id

TemplateRoute 与路由更改事件非常搭配:

troute = TemplateRoute(page.route)

if troute.match("/books/:id"):
print("Book view ID:", troute.id)
elif troute.match("/account/:account_id/orders/:order_id"):
print("Account:", troute.account_id, "Order:", troute.order_id)
else:
print("Unknown route")

你可以在这里阅读更多关于 repath 库支持的模板语法。

今天就到这里!

尝试 Flet告诉我们你的想法吧!

新版本发布:拖放、绝对定位和可点击容器

· 阅读需 2 分钟
Feodor Fitsner
Flet 创始人兼开发者

我们刚刚发布了 Flet 0.1.41,其中包含拖放支持以及其他一些不错的功能,如堆栈中控件的绝对定位和可点击容器!

拖放

在 Flet 中实现拖放非常愉快——这要归功于 Flutter 中智能的拖放实现!您只需使用 "draggable" 控件将其拖到 "drag target" 上,当拖动项被放置时,会调用 on_accept 事件处理程序。

查看 拖放示例

探索 DraggableDragTarget 控件,它们的属性和事件。

堆栈中的绝对定位

现在所有可见控件都有 lefttoprightbottom 属性,可以让它们在 Stack 内进行绝对定位,例如:

import flet as ft

def main(page: ft.Page):

page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
page.vertical_alignment = ft.MainAxisAlignment.CENTER

page.add(
ft.Container(
ft.Stack(
[
ft.Text("1", color=ft.colors.WHITE),
ft.Text("2", color=ft.colors.WHITE, right=0),
ft.Text("3", color=ft.colors.WHITE, right=0, bottom=0),
ft.Text("4", color=ft.colors.WHITE, left=0, bottom=0),
ft.Text("5", color=ft.colors.WHITE, left=40, top=35),
]
),
border_radius=8,
padding=5,
width=100,
height=100,
bgcolor=ft.colors.BROWN_700,
)
)

ft.app(target=main)

可点击容器

Container 控件获得了 on_click 事件,使您可以将任何控件变成按钮,并在 ink 设置为 True 时具有漂亮的材质波纹效果!

查看上述示例的 源代码

试用 Flet告诉我们 您的想法!