📱 平台组件详解

Flutter 提供了与平台交互的组件,用于处理系统级别的功能,如安全区域、屏幕信息、平台检测等。

🔙 WillPopScope

WillPopScope 用于拦截返回按钮事件,防止用户意外退出页面。

渲染预览

9:41
📶 🔋
WillPopScope 示例
🔙
点击返回按钮
将显示确认对话框
⚠️ 确认退出
确定要退出吗?
取消
确定

基本用法

WillPopScope(
  onWillPop: () async {
    // 显示确认对话框
    final shouldPop = await showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('确认退出'),
        content: Text('确定要退出吗?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: Text('取消'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: Text('确定'),
          ),
        ],
      ),
    );
    return shouldPop ?? false;
  },
  child: Scaffold(
    appBar: AppBar(title: Text('页面')),
    body: Center(child: Text('内容')),
  ),
)

常用属性

属性 类型 说明
onWillPop Future Function() 返回前的回调
child Widget 子组件
💡 提示:onWillPop 返回 true 允许退出,返回 false 阻止退出。

🛡️ SafeArea

SafeArea 用于自动避开系统 UI(如刘海屏、状态栏、底部导航栏等)的安全区域。

渲染预览

❌ 未使用 SafeArea
内容被刘海屏遮挡
✗ 未使用 SafeArea
✓ 使用 SafeArea
内容避开刘海屏
✓ 使用 SafeArea

基本用法

SafeArea(
  child: Scaffold(
    appBar: AppBar(title: Text('SafeArea 示例')),
    body: Column(
      children: [
        Container(
          height: 200,
          color: Colors.blue,
          child: Center(child: Text('蓝色区域')),
        ),
        Container(
          height: 200,
          color: Colors.red,
          child: Center(child: Text('红色区域')),
        ),
      ],
    ),
  ),
)

// 只在顶部避开
SafeArea(
  top: true,
  bottom: false,
  left: true,
  right: true,
  child: Text('内容'),
)

常用属性

属性 类型 说明
top bool 是否避开顶部
bottom bool 是否避开底部
left bool 是否避开左侧
right bool 是否避开右侧
minimum EdgeInsets 最小边距
💡 提示:在 iPhone X 及以后的设备上,SafeArea 非常重要,可以避免内容被刘海屏遮挡。

📐 MediaQuery

MediaQuery 用于获取屏幕信息,如屏幕尺寸、方向、文本缩放等。

渲染预览

📊 MediaQuery 信息
屏幕尺寸
375 x 812
屏幕方向
Portrait
顶部安全区域
44.0 px
底部安全区域
34.0 px
文本缩放
1.0
设备类型
📱 手机
亮度模式
☀️ 亮色模式

基本用法

class MediaQueryExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);

    return Scaffold(
      appBar: AppBar(title: Text('MediaQuery 示例')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('屏幕宽度: ${mediaQuery.size.width}'),
            Text('屏幕高度: ${mediaQuery.size.height}'),
            Text('屏幕方向: ${mediaQuery.orientation}'),
            Text('顶部安全区域: ${mediaQuery.padding.top}'),
            Text('底部安全区域: ${mediaQuery.padding.bottom}'),
            Text('文本缩放: ${mediaQuery.textScaleFactor}'),
            Text('是否为平板: ${mediaQuery.size.shortestSide > 600}'),
          ],
        ),
      ),
    );
  }
}

常用属性

属性 类型 说明
size Size 屏幕尺寸
padding EdgeInsets 安全区域
orientation Orientation 屏幕方向
textScaleFactor double 文本缩放比例
platformBrightness Brightness 亮度模式(亮/暗)
💡 提示:MediaQuery 可以用于响应式布局,根据屏幕大小调整 UI。

🖥️ Platform

Platform 用于检测运行平台(iOS、Android、Web 等),实现平台相关的逻辑。

渲染预览

🤖
Android
Platform.isAndroid
🍎
iOS
Platform.isIOS
🌐
Web
kIsWeb
💻
Desktop
isWindows/macOS/Linux

基本用法

import 'dart:io' show Platform;

Widget build(BuildContext context) {
  return Column(
    children: [
      if (Platform.isAndroid)
        Text('当前平台: Android'),
      if (Platform.isIOS)
        Text('当前平台: iOS'),
      if (Platform.isWindows)
        Text('当前平台: Windows'),
      if (Platform.isMacOS)
        Text('当前平台: macOS'),
      if (Platform.isLinux)
        Text('当前平台: Linux'),
      if (Platform.isFuchsia)
        Text('当前平台: Fuchsia'),
      if (Platform.isWeb)
        Text('当前平台: Web'),
    ],
  );
}

// 根据平台使用不同的组件
Widget _buildButton() {
  if (Platform.isIOS) {
    return CupertinoButton(
      onPressed: () {},
      child: Text('iOS 按钮'),
    );
  } else {
    return ElevatedButton(
      onPressed: () {},
      child: Text('Android 按钮'),
    );
  }
}

常用属性

属性 类型 说明
isAndroid bool 是否为 Android
isIOS bool 是否为 iOS
isWindows bool 是否为 Windows
isMacOS bool 是否为 macOS
isLinux bool 是否为 Linux
isWeb bool 是否为 Web
operatingSystem String 操作系统名称
💡 提示:Platform 类在 Web 上不可用,Web 平台使用 kIsWeb 常量判断。