在 Flutter 中,Material 3(也称为 Material You)是 Google 最新的设计语言,它在 Material 2 的基础上进行了重大升级,提供了更个性化、更现代的设计体验。
Material 3 的主要特性
1. 动态色彩 (Dynamic Color)
Material 3 的核心特性之一是从用户壁纸中提取颜色主题。
Dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material 3 Demo',
theme: ThemeData(
useMaterial3: true, // 启用 Material 3
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple, // 从种子颜色生成完整配色
),
),
home: const MyHomePage(),
);
}
}
2. 更新的组件样式
按钮 (Buttons)
Dart
class ButtonExamples extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
FilledButton(
onPressed: () {},
child: const Text('Filled Button'),
),
const SizedBox(height: 10),
FilledButton.tonal(
onPressed: () {},
child: const Text('Tonal Button'),
),
const SizedBox(height: 10),
OutlinedButton(
onPressed: () {},
child: const Text('Outlined Button'),
),
const SizedBox(height: 10),
TextButton(
onPressed: () {},
child: const Text('Text Button'),
),
],
);
}
}
导航栏 (Navigation Bar)
Dart
class BottomNavigationExample extends StatefulWidget {
const BottomNavigationExample({super.key});
@override
State<BottomNavigationExample> createState() =>
_BottomNavigationExampleState();
}
class _BottomNavigationExampleState extends State<BottomNavigationExample> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Material 3 Navigation'),
),
body: Center(
child: Text('Selected Page: $_selectedIndex'),
),
bottomNavigationBar: NavigationBar(
selectedIndex: _selectedIndex,
onDestinationSelected: _onItemTapped,
destinations: const [
NavigationDestination(
icon: Icon(Icons.home),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.business),
label: 'Business',
),
NavigationDestination(
icon: Icon(Icons.school),
label: 'School',
),
],
),
);
}
}
3. 完整的 Material 3 主题配置
Dart
ThemeData getMaterial3Theme(bool isDark) {
return ThemeData(
useMaterial3: true,
colorScheme: isDark
? ColorScheme.dark(
primary: Colors.blue,
secondary: Colors.cyan,
background: Colors.grey[900]!,
)
: ColorScheme.light(
primary: Colors.blue,
secondary: Colors.cyan,
background: Colors.white,
),
// 或者使用 fromSeed 自动生成
// colorScheme: ColorScheme.fromSeed(
// seedColor: Colors.blue,
// brightness: isDark ? Brightness.dark : Brightness.light,
// ),
// 文字主题
textTheme: TextTheme(
displayLarge: TextStyle(
fontSize: 57,
fontWeight: FontWeight.w400,
color: isDark ? Colors.white : Colors.black87,
),
titleLarge: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w400,
color: isDark ? Colors.white : Colors.black87,
),
bodyLarge: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: isDark ? Colors.white70 : Colors.black54,
),
),
// 组件主题
cardTheme: CardTheme(
elevation: 1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
);
}
4. 响应式设计改进
Dart
class AdaptiveLayoutExample extends StatelessWidget {
const AdaptiveLayoutExample({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Adaptive Layout'),
),
body: CustomScrollView(
slivers: [
// 大屏幕顶部的应用栏
SliverAppBar.large(
title: const Text('Large App Bar'),
),
// 中等屏幕应用栏
SliverAppBar.medium(
title: const Text('Medium App Bar'),
),
// 常规应用栏
SliverAppBar(
title: const Text('Regular App Bar'),
),
// 内容区域
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
leading: Icon(
Icons.circle,
color: Theme.of(context).colorScheme.primary,
),
title: Text('Item $index'),
subtitle: Text('Subtitle for item $index'),
trailing: IconButton(
icon: const Icon(Icons.more_vert),
onPressed: () {},
),
),
childCount: 20,
),
),
],
),
);
}
}
启用 Material 3 的步骤
- 在 ThemeData 中设置 useMaterial3
Dart
MaterialApp(
theme: ThemeData(useMaterial3: true),
)
- 配置颜色方案
Dart
// 方法1: 从种子颜色生成
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue)
// 方法2: 自定义完整配色
colorScheme: ColorScheme(
primary: Colors.blue,
secondary: Colors.cyan,
// ... 其他颜色
)
-
更新组件使用新的 Widget
-
使用
NavigationBar替代BottomNavigationBar -
使用
FilledButton替代已弃用的按钮变体 -
使用
SegmentedButton进行分段选择
-