Note
目前为 Android 或 iOS 开发 Slint 应用程序时,只能使用 Rust 作为编程语言。
尽管 Slint 在移动端和桌面端的使用方式相同,但在开发过程中仍需牢记一些事项。移动平台通常具有较小的屏幕并且没有硬件键盘,这些限制无法由用户界面框架处理,而是特定于应用程序本身的。触控交互也需要相对于基于鼠标的交互的特殊处理。
本页面描述了适用于所有移动平台的注意事项。后续页面将在此基础上深入探讨平台特定的问题。
滚动
默认情况下,Slint 的 ScrollView 仅通过拖动滚动条或鼠标滚轮进行滚动。这在桌面端是可以的,但触控界面则期望在平移整个视图时进行滚动。
在 Slint 中可以这样启用:
import { ScrollView } from "std-widgets.slint";export component MyComponent { ScrollView { mouse-drag-pan-enabled: true;
// Your own elements here }}请注意,这也会在连接鼠标时启用该行为,这可能不是你期望的。这将在未来版本的 Slint 中修复。
安全区域
移动设备的操作系统开发人员试图通过将系统级覆盖区域减少到最低限度来弥补小屏幕的局限。这意味着应用程序通常可以访问整个屏幕,但仍有一些系统项覆盖在屏幕上,例如信号塔接收情况和电池状态。在 Android 上,这还包括导航按钮。此外,许多手机将前置摄像头嵌入显示屏中,只留下一小块不可访问的非矩形区域(即"刘海屏")。
应用程序通常可以绘制整个屏幕以及某些覆盖区域的下方,但用户交互并不是在所有地方都被允许。例如,绘制在前置摄像头区域下方的按钮无法被点击。因此,Android 和 iOS 定义了所谓的"安全区域":这是一个矩形区域,应用程序可以期望用户在其中与界面元素进行交互。它由一个内边距来定义,意味着它定义了应用程序窗口内一个不可见边框的厚度,该边框内应仅包含背景元素(如背景图像、图案、颜色)。此安全区域的大小在运行时也可能发生变化,例如在 Android 上底部的导航按钮显示和隐藏时。
在 Slint 中,此区域通过 Window 元素上的 Window.safe-area-insets 属性暴露。
例如,为了调试,如果你想放置一个矩形以可视化安全区域,可以这样做:
export component MainWindow inherits Window { Rectangle { background: yellow; x: root.safe-area-insets.left; y: root.safe-area-insets.top; width: root.width - root.safe-area-insets.right - root.safe-area-insets.left; height: root.height - root.safe-area-insets.bottom - root.safe-area-insets.top; }}键盘处理
自 iPhone 推出以来,现代智能手机通常不配备用于文本输入的硬件键盘。虽然有一些配件(例如蓝牙或 USB 键盘)以及提供此功能的特殊手机壳,但始终必须有软件回退方案,即"虚拟键盘"。
请注意,键盘并不总是由按钮行组成,它也可以是手写识别区域、语音输入或用于捕获文本或条形码的摄像头查看器,然后将其插入。不过所有这些都是透明处理的,因此应用程序无需关心这些,除非应用程序自己提供虚拟键盘。
虚拟键盘放置在需要文本输入的应用程序之上,进一步减少了本就有限的屏幕空间。虽然存在分体式键盘、浮动键盘等多种形式,但操作系统始终将虚拟键盘视为覆盖在应用程序窗口之上的单一矩形。
Slint 通过 Window 元素上定义该矩形的两个属性来暴露这一点:
Slint 调用操作系统以在聚焦文本输入元素时透明地打开和隐藏虚拟键盘。操作系统决定是否实际显示它,这取决于系统设置以及是否检测到硬件键盘。这在运行时也可能发生变化,例如用户在虚拟键盘可见时连接了硬件键盘(在这种情况下,操作系统可能会自行隐藏虚拟键盘)。无论如何,如果存在非浮动的虚拟键盘,Slint 会将此信息暴露给应用程序。
你可以通过检查 virtual-keyboard-width * virtual-keyboard-height 是否大于 0 来检测键盘是否显示。
有些虚拟键盘是半透明的,这意味着键盘下方的区域在一定程度上是可见的。因此,应用程序可以在该位置显示基本的视觉元素(例如纯色),以使键盘看起来像是与视觉样式融为一体。
通常,应用程序不必使用这些属性,这归功于下一节中解释的行为。
Note
虚拟键盘覆盖层的定义方式在 Android 和 iOS 之间有所不同。Android 定义窗口的内边距(与上述安全区域定义类似),而 iOS 提供一个矩形。Slint 将其统一为在两个平台上表现一致,但由于这些在数学上并不等价,在自定义虚拟键盘的某些边缘情况下可能无法正确处理。预计大多数键盘只会占据屏幕底部的一部分区域。
保持编辑区域可见
一个常见的问题是用户想要编辑的文本框最终位于虚拟键盘下方,从而变得不可见。Slint 可以通过滚动自动处理这个问题,但应用程序必须以特定方式进行结构化才能使其生效。
当键盘显示时,当前获得焦点的元素会尝试保持可见。它通过在其父元素链中(一直向上到窗口)搜索可滚动区域(Flickable)来实现这一点。如果找到了一个可滚动区域,就会指示该区域以某种方式滚动,使其与键盘的重叠尽可能小。滚动区域的边界检查会减去与键盘的重叠部分,这意味着该区域可以比正常情况滚动得更远。当键盘再次隐藏时,这种过度滚动会被自动修正。
总结一下,如果你想在虚拟键盘显示时保持文本框可见,可以像这样将其放入滚动区域中:
import { LineEdit, ScrollView } from "std-widgets.slint";export component MyView { ScrollView { mouse-drag-pan-enabled: true;
VerticalLayout { label := Text { text: "Text input"; horizontal-alignment: left; overflow: elide; }
LineEdit { placeholder-text: "Write your text"; accessible-label: label.text; } } }}如你所见,ScrollView 不必是它的直接父元素。 请注意,不支持多层嵌套的 ScrollView。
应用程序布局考虑事项
虽然触控笔和鼠标输入可以精确到像素级,但触摸输入却不能,尤其是在电容式触摸屏上。因此,面向触摸的应用程序必须注意使可交互区域尽可能大,并在触摸区域之间留出足够的间距。此外,屏幕的某些部分比其它部分更容易被握持设备的手的拇指触及。
Slint 无法在这方面提供任何帮助,因此作为应用程序开发人员,你需要牢记这些,特别是在使用设备模拟器或像 Figma 这样的 UI 设计应用程序进行开发时。
我们强烈推荐阅读 Apple 的 Human Interface Guidelines 和 Google 的 Design for Android 页面。