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 进行分段选择

相关推荐
猫林老师2 小时前
Flutter for HarmonyOS开发指南(六):测试、调试与质量保障体系
flutter·华为·harmonyos
一路向北North3 小时前
网页版预编译SQL转换工具
前端·javascript·sql
把csdn当日记本的菜鸡4 小时前
js查缺补漏
开发语言·javascript·ecmascript
zhangyao9403304 小时前
uni-app scroll-view特定情况下运用
前端·javascript·uni-app
鎏金铁匠5 小时前
跟着ECMAScript 规范,手写数组方法之map
javascript
不爱吃糖的程序媛6 小时前
Electron 智能文件分析器开发实战适配鸿蒙
前端·javascript·electron
flashlight_hi6 小时前
LeetCode 分类刷题:3217. 从链表中移除在数组中存在的节点
javascript·数据结构·leetcode·链表
Java追光着7 小时前
React Native 自建 JS Bundle OTA 更新系统:从零到一的完整实现与踩坑记录
javascript·react native·react.js
努力往上爬de蜗牛7 小时前
react native 运行问题和调试 --持续更新
javascript·react native·react.js