9.3 多端支持

Flutter 支持 Android、iOS、Web、桌面(Windows/macOS/Linux)多个平台从同一代码库构建。了解各端差异与适配策略是多端开发的关键。


一、Flutter Desktop

1.1 启用桌面支持

bash 复制代码
flutter config --enable-windows-desktop
flutter config --enable-macos-desktop
flutter config --enable-linux-desktop

flutter run -d macos
flutter run -d windows
flutter build macos --release

1.2 Window Manager(窗口管理)

yaml 复制代码
dependencies:
  window_manager: ^0.3.9
dart 复制代码
import 'package:window_manager/window_manager.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await windowManager.ensureInitialized();

  // 配置窗口
  await windowManager.waitUntilReadyToShow(
    const WindowOptions(
      size: Size(1200, 800),
      minimumSize: Size(800, 600),
      center: true,
      backgroundColor: Colors.transparent,
      skipTaskbar: false,
      titleBarStyle: TitleBarStyle.hidden, // 隐藏原生标题栏
    ),
    () async {
      await windowManager.show();
      await windowManager.focus();
    },
  );

  runApp(const DesktopApp());
}

// 自定义标题栏
class CustomTitleBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanStart: (_) => windowManager.startDragging(), // 拖拽移动窗口
      child: Container(
        height: 40,
        color: Theme.of(context).colorScheme.surface,
        child: Row(
          children: [
            const Expanded(child: Text('My Desktop App')),
            // 窗口控制按钮
            WindowControlButton(icon: Icons.minimize, onTap: windowManager.minimize),
            WindowControlButton(icon: Icons.crop_square, onTap: windowManager.maximize),
            WindowControlButton(icon: Icons.close, onTap: windowManager.close),
          ],
        ),
      ),
    );
  }
}

1.3 平台自适应布局

dart 复制代码
class AdaptiveLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    if (Platform.isWindows || Platform.isMacOS || Platform.isLinux) {
      // 桌面布局:侧边栏 + 主内容区
      return Row(
        children: [
          SizedBox(width: 250, child: DesktopSidebar()),
          Expanded(child: MainContent()),
        ],
      );
    }
    // 移动端布局
    return MobileLayout();
  }
}

二、Flutter Web

2.1 启用 Web 支持

bash 复制代码
flutter config --enable-web
flutter run -d chrome
flutter build web --release

2.2 Web 渲染器选择

bash 复制代码
# Canvaskit 渲染(基于 WASM,像素级一致,包体较大)
flutter build web --web-renderer canvaskit

# HTML 渲染(基于浏览器 API,包体小,兼容性好)
flutter build web --web-renderer html

# Auto(手机 html,桌面 canvaskit)
flutter build web --web-renderer auto

2.3 Web 特有适配

dart 复制代码
// 检测平台
import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:io' show Platform;

bool get isWeb => kIsWeb;
bool get isMobile => !kIsWeb && (Platform.isAndroid || Platform.isIOS);
bool get isDesktop => !kIsWeb && (Platform.isWindows || Platform.isMacOS || Platform.isLinux);

// Web URL 策略
void main() {
  usePathUrlStrategy(); // 使用路径 URL(去掉 #)
  runApp(const MyApp());
}

// SEO 元标签(web/index.html)
// <meta name="description" content="My Flutter Web App">
// <meta property="og:title" content="My App">

三、平台视图(PlatformView)

3.1 AndroidView

将 Android 原生 View 嵌入 Flutter:

dart 复制代码
// 使用 AndroidView 嵌入 Google Maps
Widget build(BuildContext context) {
  return Platform.isAndroid
      ? AndroidView(
          viewType: 'google_map_view',
          onPlatformViewCreated: _onViewCreated,
          layoutDirection: TextDirection.ltr,
        )
      : const Text('Android only');
}

// Android 侧注册 View Factory
// FlutterActivity 中
flutterEngine.platformViewsController.registry.registerViewFactory(
    "google_map_view",
    { id -> GoogleMapView(context, id) }
)

3.2 UiKitView(iOS)

dart 复制代码
Widget build(BuildContext context) {
  return Platform.isIOS
      ? UiKitView(
          viewType: 'ios_map_view',
          onPlatformViewCreated: _onViewCreated,
        )
      : const SizedBox.shrink();
}

注意: PlatformView 性能开销较大,仅在无 Flutter 替代方案时使用。


四、平台检测工具

dart 复制代码
class PlatformUtils {
  static bool get isDesktop =>
      !kIsWeb && (Platform.isWindows || Platform.isMacOS || Platform.isLinux);

  static bool get isMobile =>
      !kIsWeb && (Platform.isAndroid || Platform.isIOS);

  static bool get isWeb => kIsWeb;

  // 屏幕类型
  static ScreenSize getScreenSize(BuildContext context) {
    final width = MediaQuery.of(context).size.width;
    if (width < 600) return ScreenSize.compact;       // 手机
    if (width < 1200) return ScreenSize.medium;       // 平板
    return ScreenSize.expanded;                        // 桌面
  }
}

enum ScreenSize { compact, medium, expanded }

小结

平台 状态 主要适配点
Android / iOS ✅ 稳定 原生特性调用
Web ✅ 稳定 URL 策略、SEO、渲染器选择
macOS ✅ 稳定 窗口管理、菜单栏
Windows ✅ 稳定 窗口管理、系统托盘
Linux ✅ 稳定 GTK 适配

👉 下一章:十、测试与发布

相关推荐
ZZZMMM.zip9 小时前
基于鸿蒙HarmonyOS NEXT开发AI股票分析应用:智能投资新体验与鸿蒙Flutter框架跨端实践
人工智能·flutter·华为·harmonyos·鸿蒙
韩曙亮15 小时前
【Flutter】Flutter 进程保活 ③ ( 屏幕常亮设置 | Flutter 禁止息屏、关闭自动锁屏、屏蔽系统屏保 )
android·flutter·ios·屏幕常亮·禁止息屏
心中有国也有家15 小时前
AtomGit Flutter 鸿蒙客户端:情绪日记的时间线实现
学习·flutter·华为·harmonyos
西西学代码16 小时前
Flutter---Container
flutter
西西学代码16 小时前
Flutter---底部导航栏(2)
开发语言·javascript·flutter
浮江雾18 小时前
Flutter第二节----Dart中的常量与变量
开发语言·前端·javascript·flutter·入门
yuanlaile19 小时前
前端转 Flutter 踩坑实录:一套可落地 Flutter 鸿蒙 App 完整学习路线,建议收藏!
flutter·harmonyos·flutter开发鸿蒙·跨平台开发app·flutter深入学习
ZZZMMM.zip19 小时前
基于鸿蒙HarmonyOS NEXT开发AI天气助手应用:智能出行新体验与鸿蒙Flutter框架跨端实践
人工智能·flutter·华为·harmonyos·鸿蒙系统
心中有国也有家19 小时前
AtomGit Flutter 鸿蒙客户端:一键记录情绪的极致体验
学习·flutter·华为·harmonyos
不才难以繁此生20 小时前
HarmonyOS RDB 实战|中式美食菜谱表设计:食材、步骤与购物清单怎么落库
flutter·harmonyos·rdb·中式美食·本地持久化