CupertinoLocalizations

用于支持iOS风格(Cupertino)组件本地化的核心抽象类

CupertinoLocalizations是Flutter中用于支持iOS风格(Cupertino)组件本地化的核心抽象类。它不直接渲染UI,而是为Cupertino组件(如CupertinoDatePickerCupertinoAlertDialog)提供本地化文本资源(如日期格式、按钮标签)。其核心 逻辑是:通过实现CupertinoLocalizations的子类,定义特定语言的字符串(如“OK”按钮的翻译),使Cupertino组件能自适应不同语言环境(Locale),提升应用国际化支持。

使用场景

  • 多语言应用开发: 当应用需要支持iOS风格界面且适配多种语言(如中文、英文)时。
  • 自定义本地化资源: 当默认的本地化资源不满足需求(如特定地区方言)时,需自定义实现。
  • 与Material本地化共存: 在混合使用Material和Cupertino组件的应用中,确保Cupertino部分正确显示本地化文本。

示例

基础使用

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      // 设置支持的语言环境
      supportedLocales: [
        Locale('en', 'US'), // 英语(美国)
        Locale('zh', 'CN'), // 中文(中国)
      ],
      // 使用默认的 Cupertino 本地化代理(包含常见语言)
      localizationsDelegates: [
        ...GlobalCupertinoLocalizations.delegates, // 关键:加载 Cupertino 本地化
      ],
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('Cupertino 示例'),
      ),
      child: Center(
        child: CupertinoButton(
          child: Text('显示日期选择器'),
          onPressed: () {
            showCupertinoModalPopup(
              context: context,
              builder: (context) => CupertinoDatePicker(
                // 日期选择器会自动使用当前 Locale 的格式(如中文环境显示“年/月/日”)
                onDateTimeChanged: (date) {},
              ),
            );
          },
        ),
      ),
    );
  }
}

自定义本地化实现

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

// 自定义 CupertinoLocalizations 用于特定语言(如简体中文的变体)
class CustomChineseCupertinoLocalizations extends CupertinoLocalizations {
  const CustomChineseCupertinoLocalizations();

  
  String get datePickerMediumDate => 'yyyy年mm月dd日'; // 自定义日期格式

  
  String get alertDialogCancelButtonLabel => '取消'; // 标准翻译

  
  String get alertDialogDismissButtonLabel => '关闭'; // 自定义翻译(默认为“确定”)

  // 必须实现其他抽象方法(此处省略部分,实际需完整实现)
  // 完整接口参考:https://api.flutter.dev/flutter/cupertino/CupertinoLocalizations-class.html

  static const List<LocalizationsDelegate<dynamic>> delegates = [
    DefaultCupertinoLocalizations.delegate,
  ];

  static Future<CupertinoLocalizations> load(Locale locale) {
    return SynchronousFuture<CupertinoLocalizations>(const CustomChineseCupertinoLocalizations());
  }

  static const LocalizationsDelegate<CupertinoLocalizations> delegate = _CustomChineseDelegate();
}

class _CustomChineseDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
  const _CustomChineseDelegate();

  
  bool isSupported(Locale locale) => locale.languageCode == 'zh';

  
  Future<CupertinoLocalizations> load(Locale locale) => CustomChineseCupertinoLocalizations.load(locale);

  
  bool shouldReload(_CustomChineseDelegate old) => false;
}

// 在 App 中注册自定义代理
class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      supportedLocales: [Locale('zh', 'CN')],
      localizationsDelegates: [
        CustomChineseCupertinoLocalizations.delegate, // 使用自定义代理
        ...GlobalMaterialLocalizations.delegates,
      ],
      home: MyHomePage(),
    );
  }
}

与Material本地化混合使用

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      supportedLocales: [Locale('en'), Locale('zh')],
      localizationsDelegates: [
        ...GlobalMaterialLocalizations.delegates, // Material 本地化
        ...GlobalCupertinoLocalizations.delegates, // Cupertino 本地化
      ],
      home: Scaffold(
        appBar: AppBar(title: Text('混合本地化示例')),
        body: Center(
          child: Column(
            children: [
              MaterialButton(
                child: Text('Material 按钮'),
                onPressed: () {},
              ),
              SizedBox(height: 20),
              CupertinoButton(
                child: Text('Cupertino 按钮'),
                onPressed: () {
                  // 此对话框会正确显示 Cupertino 风格的本地化文本(如按钮标签)
                  showCupertinoDialog(
                    context: context,
                    builder: (context) => CupertinoAlertDialog(
                      title: Text('提示'),
                      actions: [
                        CupertinoDialogAction(child: Text('取消'), onPressed: () {}),
                        CupertinoDialogAction(child: Text('确认'), onPressed: () {}),
                      ],
                    ),
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注意点

常见问题

  • 资源缺失导致回退: 如果未提供当前Locale的本地化代理,Cupertino组件会回退到英语(美国)版本。务必检查supportedLocaleslocalizationsDelegates的匹配性。
  • 性能开销: 本地化代理在初始化时加载资源,避免在build方法中动态创建代理,防止重复初始化。
  • 兼容性警告: Flutter的Cupertino本地化包(cupertino_localizations)需单独引入。在pubspec.yaml中添加:
dependencies:
  flutter:
    sdk: flutter
  cupertino_localizations: ^0.1.4 # 检查最新版本

优化技巧

  • 预加载常用语言: 通过precache()方法提前加载本地化资源,减少首次渲染延迟。
  • 最小化自定义: 优先使用GlobalCupertinoLocalizations.delegates覆盖的常见语言(如en、zh),减少自定义实现的工作量。
  • 测试多语言切换: 使用WidgetsApplocaleResolutionCallback处理Locale切换逻辑,确保动态更新。

最佳实践

  • 统一代理列表: 在localizationsDelegates中先添加Cupertino代理,再添加Material代理,避免覆盖冲突。
  • 完整实现接口: 自定义CupertinoLocalizations时,必须实现所有抽象方法(约20个),否则编译失败。
  • 使用ARB文件: 对于复杂多语言项目,结合flutter_localizations和ARB文件管理资源,提高可维护性。

构造函数

CupertinoLocalizations是抽象类,无公开构造函数。其子类(如DefaultCupertinoLocalizations)通过以下方式初始化:

  • 默认实现: 通过GlobalCupertinoLocalizations.delegates自动加载,无需手动构造。
  • 自定义子类: 需实现const构造函数(如const CustomLocalizations()),并通过LocalizationsDelegate注册。

属性

属性名属性类型说明
datePickerYearString日期选择器中“年”的标签(如 "Year")。
datePickerMonthString日期选择器中“月”的标签(如 "Month")。
datePickerDayString日期选择器中“日”的标签(如 "Day")。
alertDialogCancelButtonLabelString警告对话框的“取消”按钮文本(如 "Cancel")。
alertDialogDismissButtonLabelString警告对话框的“关闭”按钮文本(如 "OK",注意与取消区别)。
timerPickerHourString时间选择器中“小时”的标签(如 "Hour")。
timerPickerMinuteString时间选择器中“分钟”的标签(如 "Minute")。
searchTextFieldPlaceholderLabelString搜索框的占位符文本(如 "Search")。

关键属性解释

  • alertDialogCancelButtonLabelalertDialogDismissButtonLabel: 最常用属性,直接影响Cupertino对话框的按钮文本。若自定义实现不一致,可能导致用户体验混淆。
  • 日期/时间相关属性(如datePickerYear): 控制日期选择器的显示格式。若未正确本地化,用户可能看到英文标签,破坏界面一致性。
  • 性能提示: 这些属性在组件构建时被频繁调用,避免在getter中执行复杂计算,建议直接返回常量字符串。