Skip to content

平台差异处理

Flutter 的一大优势是"一套代码,多端运行",但现实中不同平台往往有不同的设计规范和行为习惯。你需要在代码中识别平台,并做出差异化处理。

判断当前平台

方式一:defaultTargetPlatform(推荐)

dart
import 'package:flutter/foundation.dart';

if (defaultTargetPlatform == TargetPlatform.android) {
  // Android 平台逻辑
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
  // iOS 平台逻辑
}
对应平台
TargetPlatform.androidAndroid
TargetPlatform.iOSiOS
TargetPlatform.macOSmacOS
TargetPlatform.windowsWindows
TargetPlatform.linuxLinux

鸿蒙平台

使用 flutter-ohos 时,鸿蒙平台返回的也是 TargetPlatform.android。如果需要区分 Android 和鸿蒙,需要额外判断。

方式二:dart:io 的 Platform 类

dart
import 'dart:io';

if (Platform.isAndroid) {
  // Android
} else if (Platform.isIOS) {
  // iOS
}

注意

dart:ioPlatform在 Web 平台不可用,调用会抛异常。如果你的项目需要支持 Web,请使用 defaultTargetPlatform 或先用 kIsWeb 做判断。

方式三:kIsWeb(Web 平台专用)

dart
import 'package:flutter/foundation.dart';

if (kIsWeb) {
  // Web 平台逻辑
}

区分 Android 与鸿蒙

dart
Future<bool> isHarmonyOS() async {
  if (defaultTargetPlatform != TargetPlatform.android) {
    return false;
  }
  try {
    final channel = const MethodChannel('device_info');
    final result = await channel.invokeMethod<String>('getPlatform');
    return result == 'ohos';
  } on PlatformException {
    return false;
  }
}

条件渲染:根据平台显示不同 UI

基础写法

dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class PlatformSettingsPage extends StatelessWidget {
  const PlatformSettingsPage({super.key});

  @override
  Widget build(BuildContext context) {
    // ─── ★ 根据平台条件渲染 ──────────────
    if (defaultTargetPlatform == TargetPlatform.iOS) {
      // ─── ★ CupertinoPageScaffold iOS 风格 ──────────────
      return CupertinoPageScaffold(
        navigationBar: const CupertinoNavigationBar(middle: Text('设置')),
        child: SafeArea(
          child: Center(child: Text('iOS 风格页面', style: CupertinoTheme.of(context).textTheme.navTitleTextStyle)),
        ),
      );
      // ─── ☆ CupertinoPageScaffold iOS 风格 ──────────────
    }
    // ─── ☆ 根据平台条件渲染 ──────────────
    return Scaffold(
      appBar: AppBar(title: const Text('设置')),
      body: const Center(child: Text('Material 风格页面')),
    );
  }
}

### 封装 PlatformWidget

```dart
class PlatformWidget extends StatelessWidget {
  const PlatformWidget({
    super.key,
    required this.android,
    required this.ios,
    this.macOS,
    this.windows,
  });

  final WidgetBuilder android;
  final WidgetBuilder ios;
  final WidgetBuilder? macOS;
  final WidgetBuilder? windows;

  @override
  Widget build(BuildContext context) {
    switch (defaultTargetPlatform) {
      case TargetPlatform.iOS:
        return ios(context);
      case TargetPlatform.macOS:
        return macOS?.call(context) ?? ios(context);
      case TargetPlatform.windows:
        return windows?.call(context) ?? android(context);
      default:
        return android(context);
    }
  }
}

平台特定的交互适配

页面返回

dart
Widget build(BuildContext context) {
  return PopScope(
    canPop: true,
    onPopInvokedWithResult: (didPop, result) {
      if (!didPop) {
        // 自定义返回逻辑
      }
    },
    child: Scaffold(...),
  );
}

滚动物理效果

平台默认效果Physics
Android到顶/底有光晕效果ClampingScrollPhysics
iOS到顶/底有回弹效果BouncingScrollPhysics

手动指定:

dart
import 'package:flutter/material.dart';

class BouncingListPage extends StatelessWidget {
  const BouncingListPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('滚动物理效果')),
      body: ListView.builder(
        physics: const BouncingScrollPhysics(),  // 强制 iOS 风格回弹
        itemCount: 30,
        itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
      ),
    );
  }
}

---

## 平台特定的代码隔离

当不同平台的实现差异很大时,可以利用 Dart 的条件导入:

lib/ ├── platform_service.dart # 统一接口 ├── platform_service_stub.dart # Web 空实现 └── platform_service_io.dart # 移动端实现


```dart
// lib/platform_service.dart
export 'platform_service_stub.dart'
    if (dart.library.io) 'platform_service_io.dart';

abstract class PlatformService {
  String getDeviceInfo();
}

这种方式在编译期选择对应平台的实现,不会引入不必要的代码,但语法较复杂,一般在大型项目中使用。对于初学者,简单的 if-else 判断已经足够。


平台差异处理原则

原则说明
默认自适应Flutter 的 Scaffold、AppBar 等组件已内置平台适配,优先使用默认行为
按需判断只在确实需要差异的地方做判断,不要过度使用
集中管理将平台判断逻辑封装到工具类或组件中,避免到处散落 if-else
充分测试每个平台的差异行为都要在真机或模拟器上验证

下一步

基于 Flutter 官方文档整理