API

nsh/android

nsh/android 包含只有 Android 才有的 API。Rust 代码调用 nsh_core::ui::prelude 中对应的函数(toast、on_back_press),并用 os() == Os::Android 判断平台;TSX 导入这个模块,它在所有平台上都可以导入,因此同一个 bundle 可以在所有平台运行:在其他平台上它的函数什么也不做,isAvailable 告诉你当前是否在 Android 上。

use nsh_core::{platform::Os, ui::prelude::*}; // os、toast、ToastDuration、on_back_press

元素和组件的 Android 专有属性不在这里:在 TSX 中它们放在 android={{…}} 属性中(例如 <View android={{ elevation: 4, ripple: … }} />)。见平台专有代码。

#isAvailable

const isAvailable: boolean;

在 Android 上为 true,其他平台为 false。Rust:os() == Os::Android。

#Toast

const Toast: {
  show(message: string, duration?: "short" | "long" | null): void;
};

在屏幕底部显示一条简短消息(Android 的 toast)。duration 默认为 "short"。Rust:toast(message, ToastDuration::Short)(或 ToastDuration::Long),在其他平台上什么也不做。

use nsh_base::alert_dialog;
use nsh_core::{platform::Os, ui::prelude::*};

fn notify(message: &str) {
    if os() == Os::Android {
        toast(message, ToastDuration::Short);
    } else {
        let message = message.to_string();
        spawn(async move {
            let _ = alert_dialog().title("Done").description(message).action("OK").show().await;
        });
    }
}

#BackHandler

const BackHandler: {
  onBackPress(listener: () => boolean | void): () => void;
  exitApp(): void;
};

系统返回键和返回手势。对话框先处理返回操作(关闭对话框);然后运行 BackHandler 的监听器,最后添加的最先运行;都不处理时,最上层的导航栈出栈,没有可返回的页面时应用退出。

成员Rust说明
onBackPress(listener)on_back_press(listener)listener 处理了这次返回时返回 true。返回一个停止监听的函数;在组件渲染(或 effect 运行)期间添加的监听器随之停止,Rust 与 TSX 都是如此。
exitApp()监听器返回 false退出应用。Rust 监听器返回 false 时,返回操作继续传递,由导航栈返回或应用退出。
use nsh_base::alert_dialog;
use nsh_core::ui::prelude::*;

#[component]
fn Editor() -> impl IntoElement {
    let dirty = signal(false);
    on_back_press(move || {
        if !dirty.get_untracked() {
            return false; // 交给应用返回或退出
        }
        spawn(async move {
            let answer = alert_dialog().title("Discard changes?").cancel("Keep").destructive("Discard").show().await;
            if answer == Ok(Some("Discard".into())) {
                dirty.set(false); // 下一次返回即离开
            }
        });
        true
    });
    // ...
}

状态栏在 iOS 和 Android 上都由 nsh/base 中页面和对话框的 statusBar 设置。