前言:
通过 ThemeData(全局主题)和工具类,实现颜色、字体、组件样式的统一管理,减少重复代码,便于后期维护;通过平台判断,实现 Android/iOS/Web 端的差异化适配,兼顾原生体验。
关键要点:
- Material 风格对应 Android,Cupertino 风格对应 iOS,根据需求选择入口;
- ThemeData 是全局主题核心,子组件通过 Theme.of(context) 获取样式;
- 颜色、字体、样式需封装工具类,禁止硬编码;
- 平台适配优先"自动适配+手动差异化",避免两套完全独立的 UI。
一、总览
本讲核心目标是帮助开发者掌握 Flutter 中"风格与主题统一"的实现方法,解决多页面、多组件的视觉一致性问题,同时兼顾不同平台(Android/iOS)的原生视觉体验。
通过学习 Material 风格、Cupertino iOS 风格的差异与应用,掌握 ThemeData 全局主题的配置技巧,实现颜色、字体、组件样式的统一管理,并理解平台适配的核心逻辑与差异化处理方案,最终能独立开发出视觉统一、平台适配的 Flutter 应用。
简单来说,本章要解决的核心问题:如何让 App 所有页面"看起来像一个整体",同时在 Android 和 iOS 上都能符合用户的使用习惯(比如 Android 用 Material 按钮,iOS 用 Cupertino 按钮)。
Flutter 风格与主题统一的底层逻辑,核心是"主题全局管理+组件风格适配",底层结构分为 4 层,自上而下层层依赖,具体结构如下:

结构说明:
- 顶层:应用入口决定整体风格基调(MaterialApp 对应 Android 风格,CupertinoApp 对应 iOS 风格,也可混合使用);
- 核心层:全局主题(ThemeData/CupertinoThemeData)是风格统一的核心,存储全局共享的颜色、字体、组件样式;
- 中间层:主题属性通过"继承+覆盖"的方式,传递给所有子组件,确保组件样式统一;
- 底层:组件根据全局主题和平台判断,渲染对应风格的 UI,实现"统一风格+平台差异化"。
二、核心知识点
2.1 Material 风格与 Cupertino iOS 风格
Flutter 提供两种主流 UI 风格,分别对应 Android 和 iOS 原生视觉,开发者可根据需求选择单一风格或混合适配。
2.1.1 Material 风格(Android 原生风格)
基于 Google 的 Material Design 设计规范,特点是立体感、阴影、圆角、波纹效果,适合 Android 平台。
核心属性:
- MaterialApp:Material 风格入口,包含 theme(全局主题)、home(首页)、routes(路由)等核心属性;
- Scaffold:Material 风格页面容器,包含 appBar(导航栏)、body(内容区)、floatingActionButton(悬浮按钮)等;
- 常用组件:ElevatedButton(悬浮按钮)、TextButton(文本按钮)、Card(卡片)、ListTile(列表项),均自带 Material 风格。
核心案例:MaterialApp 入口+基础组件
less
import 'package:flutter/material.dart';
void main() {
runApp(const MyMaterialApp());
}
class MyMaterialApp extends StatelessWidget {
const MyMaterialApp({super.key});
@override
Widget build(BuildContext context) {
// Material风格入口
return MaterialApp(
title: 'Material风格示例',
home: Scaffold(
// Material专属导航栏
appBar: AppBar(title: const Text('Material App')),
body: Center(
// Material专属按钮(带波纹效果)
child: ElevatedButton(
onPressed: () {},
child: const Text('点击按钮'),
),
),
),
);
}
}

注意事项:
- Material 组件必须包裹在 MaterialApp 或 Material 组件内部,否则会报错;
- 波纹效果默认开启,可通过 splashColor 关闭或修改。
2.1.2 Cupertino iOS 风格
基于 Apple 的 iOS 设计规范,特点是扁平化、无阴影(或浅阴影)、圆角柔和,适合 iOS 平台,需导入 cupertino_icons 依赖。
核心属性:
- CupertinoApp:iOS 风格入口,包含 theme(CupertinoThemeData)、home、routes 等;
- CupertinoPageScaffold:iOS 风格页面容器,包含 navigationBar(导航栏)、child(内容区);
- 常用组件:CupertinoButton(按钮)、CupertinoTextField(输入框)、CupertinoListTile(列表项)、CupertinoAlertDialog(弹窗)。
核心案例:CupertinoApp 入口+基础组件
less
import 'package:flutter/cupertino.dart';
void main() {
runApp(const MyCupertinoApp());
}
class MyCupertinoApp extends StatelessWidget {
const MyCupertinoApp({super.key});
@override
Widget build(BuildContext context) {
// iOS风格入口
return CupertinoApp(
title: 'Cupertino风格示例',
home: CupertinoPageScaffold(
// iOS专属导航栏
navigationBar: const CupertinoNavigationBar(
middle: Text('Cupertino App'),
),
child: Center(
// iOS专属按钮(无波纹,点击有高亮效果)
child: CupertinoButton(
color: CupertinoColors.activeBlue,
onPressed: () {},
child: const Text('点击按钮'),
),
),
),
);
}
}

注意事项:
- 需在 pubspec.yaml 中添加 cupertino_icons: ^1.0.6 依赖,否则图标无法正常显示;
- Cupertino 组件不支持 Material 风格的波纹效果,点击反馈为高亮效果;
- 导航栏默认无返回按钮,需手动添加。
3.2 ThemeData 全局主题(核心)
ThemeData 是 Material 风格的全局主题配置类,可统一管理 App 所有组件的颜色、字体、样式,实现"一处修改,全局生效";Cupertino 风格对应 CupertinoThemeData,用法类似。
核心属性(ThemeData) :
- 颜色相关:primaryColor(主色调)、primarySwatch(主色调系列)、accentColor(强调色)、backgroundColor(背景色)、errorColor(错误色);
- 字体相关:fontFamily(全局字体)、textTheme(文本样式集合,包含标题、正文、提示文字等);
- 组件样式相关:elevatedButtonTheme(悬浮按钮样式)、textButtonTheme(文本按钮样式)、cardTheme(卡片样式)、appBarTheme(导航栏样式);
- 其他:brightness(亮度,light/dark)、scaffoldBackgroundColor(页面背景色)。
核心案例:配置全局主题(颜色+字体+按钮样式)
less
import 'package:flutter/material.dart';
void main() {
runApp(const MyThemedApp());
}
class MyThemedApp extends StatelessWidget {
const MyThemedApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '全局主题示例',
// 全局主题配置
theme: ThemeData(
// 1. 颜色主题(全局主色调、次要色调、错误色)
primaryColor: Colors.blue, // 主色调(导航栏、按钮等)
primarySwatch: Colors.blue, // 主色调系列(用于生成不同深浅的颜色)
shadowColor: Colors.orange,// 阴影颜色(用于按钮、卡片等)
// 2. 字体配置(全局字体)
fontFamily: 'PingFang SC', // 全局字体(需导入字体资源)
textTheme: const TextTheme(
// 标题字体
titleLarge: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
// 正文字体
bodyLarge: TextStyle(fontSize: 16, color: Colors.grey),
// 提示文字字体
bodySmall: TextStyle(fontSize: 14, color: Colors.grey),
),
// 3. 按钮样式(全局统一按钮)
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
textStyle: const TextStyle(fontSize: 16),
),
),
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
// 从全局主题中获取样式(无需重复配置)
final textTheme = Theme.of(context).textTheme;
return Scaffold(
appBar: AppBar(title: Text('全局主题演示', style: textTheme.titleLarge)),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('这是正文内容,字体和颜色全局统一', style: textTheme.bodyLarge),
const SizedBox(height: 20),
Text('这是提示文字', style: textTheme.bodySmall),
const SizedBox(height: 20),
// 按钮样式全局统一
ElevatedButton(
onPressed: () {},
child: const Text('全局样式按钮'),
),
const SizedBox(height: 20),
// 手动覆盖全局样式(特殊需求)
ElevatedButton(
style: ElevatedButton.styleFrom(foregroundColor: Colors.green),
onPressed: () {},
child: const Text('覆盖全局样式按钮'),
),
],
),
),
);
}
}

注意事项:
- 全局主题需在 MaterialApp 的 theme 属性中配置,子组件通过 Theme.of(context) 获取主题样式;
- 可通过"局部主题"(Theme 组件)覆盖全局主题,满足特殊页面/组件的样式需求;
- 导入自定义字体时,需在 pubspec.yaml 中配置 fonts 路径,否则 fontFamily 不生效;
- Cupertino 风格的全局主题用 CupertinoThemeData,属性类似(如 primaryColor、textTheme 对应 textTheme)。
3.3 颜色、字体、样式统一
在全局主题的基础上,进一步规范颜色、字体、组件样式的使用,避免混乱,核心是"统一命名、统一引用、禁止硬编码"。
核心案例:规范颜色和字体(封装工具类)
php
import 'package:flutter/material.dart';
// 1. 统一颜色管理(封装工具类,避免硬编码)
class AppColors {
static const primary = Color(0xFF2196F3); // 主色调
static const secondary = Color(0xFFFF9800); // 强调色
static const success = Color(0xFF4CAF50); // 成功色
static const error = Color(0xFFF44336); // 错误色
static const textPrimary = Color(0xFF333333); // 正文主色
static const textSecondary = Color(0xFF666666); // 正文次要色
static const background = Color(0xFFF5F5F5); // 页面背景色
}
// 2. 统一字体管理
class AppFonts {
static const fontFamily = 'PingFang SC';
// 标题字体
static const titleLarge = TextStyle(
fontFamily: fontFamily,
fontSize: 20,
fontWeight: FontWeight.bold,
color: AppColors.textPrimary,
);
// 正文字体
static const bodyLarge = TextStyle(
fontFamily: fontFamily,
fontSize: 16,
color: AppColors.textPrimary,
);
// 提示文字字体
static const bodySmall = TextStyle(
fontFamily: fontFamily,
fontSize: 14,
color: AppColors.textSecondary,
);
}
// 3. 统一组件样式(按钮、卡片等)
class AppStyles {
// 统一按钮样式
static final elevatedButtonStyle = ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
borderRadius: BorderRadius.circular(8),
textStyle: AppFonts.bodyLarge,
);
// 统一卡片样式
static final cardStyle = CardTheme(
elevation: 2,
borderRadius: BorderRadius.circular(12),
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
);
}
// 应用入口(使用统一样式)
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '样式统一示例',
theme: ThemeData(
primaryColor: AppColors.primary,
scaffoldBackgroundColor: AppColors.background,
fontFamily: AppFonts.fontFamily,
textTheme: TextTheme(
titleLarge: AppFonts.titleLarge,
bodyLarge: AppFonts.bodyLarge,
bodySmall: AppFonts.bodySmall,
),
elevatedButtonTheme: ElevatedButtonThemeData(style: AppStyles.elevatedButtonStyle),
cardTheme: AppStyles.cardStyle,
),
home: const StyleUnificationPage(),
);
}
}
class StyleUnificationPage extends StatelessWidget {
const StyleUnificationPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('样式统一演示')),
body: ListView(
children: [
// 统一卡片样式
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('卡片标题', style: AppFonts.titleLarge),
const SizedBox(height: 8),
Text('这是卡片正文,颜色、字体、间距都统一配置,无需重复编写。', style: AppFonts.bodyLarge),
],
),
),
),
// 统一按钮样式
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: ElevatedButton(
onPressed: () {},
child: const Text('统一样式按钮'),
),
),
// 引用统一颜色
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text('这是提示文字,颜色统一', style: AppFonts.bodySmall),
),
],
),
);
}
}

注意事项:
- 颜色、字体、样式需封装成工具类(如 AppColors、AppFonts),禁止在组件中直接写色值(如 Color(0xFF2196F3))、字体大小,便于后期统一修改;
- 所有组件优先使用全局主题或工具类中的样式,特殊情况可局部覆盖,但需注明原因;
- 字体需统一(如全用 PingFang SC 或 Roboto),避免同一页面出现多种字体。
3.4 平台适配与差异化
平台适配的核心是"统一风格基础上,兼顾平台原生体验",Flutter 提供两种适配方式:自动适配(根据运行平台自动切换组件)、手动适配(根据平台判断渲染不同组件)。
核心属性与方法:
- Platform.isAndroid / Platform.isIOS:判断当前运行平台(需导入 dart:io 包);
- 自动适配:根据平台选择 MaterialApp 或 CupertinoApp 作为入口;
- 手动适配:通过 if-else 判断平台,渲染不同组件(如按钮、弹窗、导航栏);
- 平台专属方法:showDialog(Android 弹窗)、showCupertinoDialog(iOS 弹窗)。
核心案例:平台差异化适配(自动+手动)
less
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:io'; // 用于判断平台
void main() {
runApp(const PlatformAdaptationApp());
}
class PlatformAdaptationApp extends StatelessWidget {
const PlatformAdaptationApp({super.key});
@override
Widget build(BuildContext context) {
// 方式1:自动适配(根据平台选择入口)
return Platform.isAndroid
? MaterialApp(
title: 'Android 适配',
theme: ThemeData(primarySwatch: Colors.blue),
home: const PlatformAdaptationPage(),
)
: CupertinoApp(
title: 'iOS 适配',
theme: CupertinoThemeData(primaryColor: CupertinoColors.activeBlue),
home: const PlatformAdaptationPage(),
);
}
}
class PlatformAdaptationPage extends StatelessWidget {
const PlatformAdaptationPage({super.key});
// 封装:根据平台返回不同按钮
Widget _buildPlatformButton() {
if (Platform.isAndroid) {
// Android:Material 按钮
return ElevatedButton(
onPressed: () => _showPlatformDialog(),
child: const Text('点击弹窗'),
);
} else {
// iOS:Cupertino 按钮
return CupertinoButton(
color: CupertinoColors.activeBlue,
onPressed: () => _showPlatformDialog(),
child: const Text('点击弹窗'),
);
}
}
// 封装:根据平台返回不同弹窗
void _showPlatformDialog() {
if (Platform.isAndroid) {
// Android:Material 弹窗
showDialog(
context: navigatorKey.currentContext!,
builder: (context) => AlertDialog(
title: const Text('提示'),
content: const Text('这是Android平台弹窗'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('确定'),
),
],
),
);
} else {
// iOS:Cupertino 弹窗
showCupertinoDialog(
context: navigatorKey.currentContext!,
builder: (context) => CupertinoAlertDialog(
title: const Text('提示'),
content: const Text('这是iOS平台弹窗'),
actions: [
CupertinoDialogAction(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
CupertinoDialogAction(
onPressed: () => Navigator.pop(context),
child: const Text('确定'),
),
],
),
);
}
}
@override
Widget build(BuildContext context) {
// 方式2:手动适配(同一页面中,根据平台渲染不同组件)
return Scaffold(
// 导航栏适配
appBar: Platform.isAndroid
? AppBar(title: const Text('平台适配演示'))
: CupertinoNavigationBar(middle: const Text('平台适配演示')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 平台差异化按钮
_buildPlatformButton(),
const SizedBox(height: 20),
// 平台差异化文本(字体、颜色)
Text(
Platform.isAndroid ? '当前是Android平台' : '当前是iOS平台',
style: Platform.isAndroid
? Theme.of(context).textTheme.titleLarge
: CupertinoTheme.of(context).textTheme.navTitleTextStyle,
),
],
),
),
);
}
}
// 全局导航键(用于弹窗获取上下文)
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
注意事项:
- 平台适配不是"两套完全独立的 UI",而是"统一核心样式,差异化细节",避免用户体验割裂;
- 使用 Platform 类需注意:Web 端不支持 dart:io 包,若需适配 Web,需用 kIsWeb(from flutter/foundation.dart)判断;
- 可使用第三方插件(如 flutter_platform_widgets)简化平台适配代码,无需手动写 if-else。
四、综合应用案例
需求:开发一个"个人中心"页面,要求:
① 风格统一(颜色、字体、组件样式)
② 平台适配(Android 用 Material 风格,iOS 用 Cupertino 风格)
③ 全局主题控制
④ 包含导航栏、头像、列表、按钮等组件。
完整代码:
less
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
// 1. 统一颜色管理
class AppColors {
static const primary = Color(0xFF2196F3);
static const secondary = Color(0xFFFF9800);
static const textPrimary = Color(0xFF333333);
static const textSecondary = Color(0xFF666666);
static const background = Color(0xFFF5F5F5);
static const cardBackground = Color(0xFFFFFFFF);
}
// 2. 统一字体管理
class AppFonts {
static const fontFamily = kIsWeb ? 'Arial' : 'PingFang SC'; // Web端适配字体
static const titleLarge = TextStyle(
fontFamily: fontFamily,
fontSize: 20,
fontWeight: FontWeight.bold,
color: AppColors.textPrimary,
);
static const bodyLarge = TextStyle(
fontFamily: fontFamily,
fontSize: 16,
color: AppColors.textPrimary,
);
static const bodySmall = TextStyle(
fontFamily: fontFamily,
fontSize: 14,
color: AppColors.textSecondary,
);
}
// 3. 统一组件样式
class AppStyles {
// 按钮样式
static final elevatedButtonStyle = ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
borderRadius: BorderRadius.circular(8),
textStyle: AppFonts.bodyLarge,
);
static final cupertinoButtonStyle = CupertinoButtonData(
color: AppColors.primary,
);
// 卡片样式
static final cardStyle = CardTheme(
elevation: 2,
borderRadius: BorderRadius.circular(12),
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
color: AppColors.cardBackground,
);
// 列表项样式
static final listTileStyle = ListTileThemeData(
textColor: AppColors.textPrimary,
iconColor: AppColors.primary,
);
}
// 4. 全局主题配置
ThemeData get androidTheme => ThemeData(
primaryColor: AppColors.primary,
scaffoldBackgroundColor: AppColors.background,
fontFamily: AppFonts.fontFamily,
textTheme: TextTheme(
titleLarge: AppFonts.titleLarge,
bodyLarge: AppFonts.bodyLarge,
bodySmall: AppFonts.bodySmall,
),
elevatedButtonTheme: ElevatedButtonThemeData(style: AppStyles.elevatedButtonStyle),
cardTheme: AppStyles.cardStyle,
listTileTheme: AppStyles.listTileStyle,
);
CupertinoThemeData get iosTheme => CupertinoThemeData(
primaryColor: AppColors.primary,
scaffoldBackgroundColor: AppColors.background,
textTheme: CupertinoTextThemeData(
navTitleTextStyle: AppFonts.titleLarge,
bodyTextStyle: AppFonts.bodyLarge,
captionTextStyle: AppFonts.bodySmall,
),
);
// 5. 主入口(平台自动适配)
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
if (kIsWeb) {
// Web端默认使用Material风格
return MaterialApp(
title: '个人中心(Web)',
theme: androidTheme,
home: const ProfilePage(),
navigatorKey: navigatorKey,
);
} else if (Platform.isAndroid) {
// Android端使用Material风格
return MaterialApp(
title: '个人中心(Android)',
theme: androidTheme,
home: const ProfilePage(),
navigatorKey: navigatorKey,
);
} else {
// iOS端使用Cupertino风格
return CupertinoApp(
title: '个人中心(iOS)',
theme: iosTheme,
home: const ProfilePage(),
navigatorKey: navigatorKey,
);
}
}
}
// 全局导航键
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// 6. 个人中心页面(核心页面,整合所有技术)
class ProfilePage extends StatelessWidget {
const ProfilePage({super.key});
// 封装:平台适配按钮
Widget _buildLogoutButton() {
if (kIsWeb || Platform.isAndroid) {
return ElevatedButton(
style: AppStyles.elevatedButtonStyle,
onPressed: () => _showLogoutDialog(),
child: const Text('退出登录'),
);
} else {
return CupertinoButton(
color: AppColors.primary,
onPressed: () => _showLogoutDialog(),
child: const Text('退出登录'),
);
}
}
// 封装:平台适配弹窗
void _showLogoutDialog() {
if (kIsWeb || Platform.isAndroid) {
showDialog(
context: navigatorKey.currentContext!,
builder: (context) => AlertDialog(
title: const Text('确认退出'),
content: const Text('确定要退出当前账号吗?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('确定'),
),
],
),
);
} else {
showCupertinoDialog(
context: navigatorKey.currentContext!,
builder: (context) => CupertinoAlertDialog(
title: const Text('确认退出'),
content: const Text('确定要退出当前账号吗?'),
actions: [
CupertinoDialogAction(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
CupertinoDialogAction(
onPressed: () => Navigator.pop(context),
child: const Text('确定'),
),
],
),
);
}
}
// 封装:平台适配导航栏
Widget _buildAppBar() {
if (kIsWeb || Platform.isAndroid) {
return AppBar(
title: const Text('个人中心'),
centerTitle: true,
backgroundColor: AppColors.primary,
);
} else {
return CupertinoNavigationBar(
middle: const Text('个人中心'),
backgroundColor: AppColors.primary,
textStyle: const TextStyle(color: Colors.white),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildAppBar(),
body: ListView(
children: [
// 头像区域
Padding(
padding: const EdgeInsets.symmetric(vertical: 24),
child: Center(
child: Column(
children: [
// 头像
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: AppColors.secondary,
borderRadius: BorderRadius.circular(50),
image: const DecorationImage(
image: NetworkImage('https://via.placeholder.com/100'),
fit: BoxFit.cover,
),
),
),
const SizedBox(height: 12),
// 用户名(全局字体)
Text('Flutter 开发者', style: AppFonts.titleLarge),
const SizedBox(height: 4),
// 简介(全局字体)
Text('专注 Flutter 学习与开发', style: AppFonts.bodySmall),
],
),
),
),
// 功能列表(全局列表样式)
Card(
child: Column(
children: [
ListTile(
leading: const Icon(Icons.person),
title: const Text('个人资料'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () {},
),
const Divider(height: 1),
ListTile(
leading: const Icon(Icons.settings),
title: const Text('设置'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () {},
),
const Divider(height: 1),
ListTile(
leading: const Icon(Icons.help),
title: const Text('帮助与反馈'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () {},
),
],
),
),
// 退出登录按钮(平台适配)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24),
child: _buildLogoutButton(),
),
],
),
);
}
}

案例说明:
- 整合点:统一颜色/字体/组件样式(工具类封装)、全局主题配置(androidTheme/iosTheme)、平台适配(自动选择入口、手动适配组件);
- 效果:在 Android 上显示 Material 风格(导航栏、按钮、弹窗),在 iOS 上显示 Cupertino 风格,Web 端默认使用 Material 风格,且所有页面颜色、字体、样式统一;
- 可扩展性:如需修改主色调,只需修改 AppColors.primary;如需修改按钮样式,只需修改 AppStyles.elevatedButtonStyle,全局生效。