Flutter Material 3设计语言详解
在 Flutter 中,Material 3(也称为 Material You)是 Google 最新的设计语言,它在 Material 2 的基础上进行了重大升级,提供了更个性化、更现代的设计体验。
Material 3 的主要特性
1. 动态色彩 (Dynamic Color)
Material 3 的核心特性之一是从用户壁纸中提取颜色主题。
import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Material 3 Demo',theme: ThemeData(useMaterial3: true, // 启用 Material 3colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple, // 从种子颜色生成完整配色),),home: const MyHomePage(),);}
}2. 更新的组件样式
按钮 (Buttons)
class ButtonExamples extends StatelessWidget {@overrideWidget 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)
class BottomNavigationExample extends StatefulWidget {const BottomNavigationExample({super.key});@overrideState<BottomNavigationExample> createState() =>_BottomNavigationExampleState();
}class _BottomNavigationExampleState extends State<BottomNavigationExample> {int _selectedIndex = 0;void _onItemTapped(int index) {setState(() {_selectedIndex = index;});}@overrideWidget 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 主题配置
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. 响应式设计改进
class AdaptiveLayoutExample extends StatelessWidget {const AdaptiveLayoutExample({super.key});@overrideWidget 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
MaterialApp(theme: ThemeData(useMaterial3: true),
)配置颜色方案
// 方法1: 从种子颜色生成
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue)// 方法2: 自定义完整配色
colorScheme: ColorScheme(primary: Colors.blue,secondary: Colors.cyan,// ... 其他颜色
)更新组件使用新的 Widget
使用
NavigationBar替代BottomNavigationBar使用
FilledButton替代已弃用的按钮变体使用
SegmentedButton进行分段选择
