Flutter Material 3设计语言详解

在 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 的步骤

  1. 在 ThemeData 中设置 useMaterial3
Dart 复制代码
MaterialApp(
  theme: ThemeData(useMaterial3: true),
)
  1. 配置颜色方案
Dart 复制代码
// 方法1: 从种子颜色生成
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue)

// 方法2: 自定义完整配色
colorScheme: ColorScheme(
  primary: Colors.blue,
  secondary: Colors.cyan,
  // ... 其他颜色
)
  1. 更新组件使用新的 Widget

    • 使用 NavigationBar 替代 BottomNavigationBar

    • 使用 FilledButton 替代已弃用的按钮变体

    • 使用 SegmentedButton 进行分段选择

相关推荐
用头发抵命6 小时前
Vue 3 中优雅地集成 Video.js 播放器:从组件封装到功能定制
开发语言·javascript·ecmascript
蓝冰凌6 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛6 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉7 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化
TON_G-T8 小时前
day.js和 Moment.js
开发语言·javascript·ecmascript
Irene19918 小时前
JavaScript 中 this 指向总结和箭头函数的作用域说明(附:call / apply / bind 对比总结)
javascript·this·箭头函数
2501_921930838 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-appearance(更推荐自带的Appearance)
javascript·react native·react.js
还是大剑师兰特8 小时前
Vue3 中 computed(计算属性)完整使用指南
前端·javascript·vue.js
csdn_aspnet9 小时前
查看 vite 与 vue 版本
javascript·vue.js