鸿蒙Flutter第三方库FlutterUnit组件百科适配——具体示例还原演示1

欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
FlutterUnit 原始仓库:
https://gitcode.com/qq_30447263/FlutterUnit

仓库版本

实际示例还原效果

原仓库效果:

还原大致效果:


1. 项目介绍

FlutterUnit 是一个功能强大的 Flutter 组件百科全书应用,旨在帮助开发者快速了解和学习 Flutter 中的各种组件。本项目参考了 FlutterUnit 开源项目的设计理念,实现了一个适配鸿蒙平台的组件展示和演示平台。

1.1 项目目标

  • 还原 FlutterUnit 应用的核心 UI 效果和功能
  • 确保应用在鸿蒙平台上的正常运行
  • 展示 Flutter 组件的使用方法和效果
  • 提供一个直观的组件展示平台,帮助开发者快速了解 Flutter 组件

1.2 技术栈

  • 框架:Flutter 3.35.7
  • 语言:Dart
  • UI 组件:Material 3
  • 状态管理:setState
  • 导航:Navigator

1.3 开源仓库地址

2. 核心功能设计

2.1 功能模块

FlutterUnit 组件百科适配项目包含以下核心功能模块:

模块名称 功能描述 实现方式
启动页面 展示应用标志和品牌信息 自定义布局和绘制
组件列表页面 展示 Flutter 组件卡片 GridView 布局
标签栏 分类展示不同类型的组件 横向滚动的标签栏
底部导航 切换不同功能页面 BottomNavigationBar

2.2 页面结构

应用采用底部导航栏的结构,包含三个主要页面:

  1. 启动页面:展示应用标志和品牌信息
  2. 组件列表页面:展示各种 Flutter 组件的卡片
  3. 收藏页面:展示用户收藏的组件(暂时使用组件列表页面)

3. 技术架构

3.1 项目结构

复制代码
lib/
├── main.dart          # 应用入口
└── components/        # 组件目录
    ├── splash/        # 启动页面组件
    ├── component_list/ # 组件列表页面组件
    └── navigation/    # 导航组件

3.2 组件结构

组件类型 职责 实现类
应用入口 初始化应用,设置主题 FlutterUnitDemoApp
主页面 管理底部导航,切换不同页面 HomePage
启动页面 展示应用标志和品牌信息 SplashScreen
组件列表页面 展示 Flutter 组件卡片 ComponentListScreen
组件卡片 展示单个组件的信息 ComponentCard

3.3 状态管理

应用使用 Flutter 内置的 setState 进行状态管理,适用于中小型应用。主要状态包括:

  • 当前选中的导航项
  • 当前选中的标签栏项
  • 组件列表数据

4. 关键代码解析

4.1 应用入口

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const FlutterUnitDemoApp());
}

class FlutterUnitDemoApp extends StatelessWidget {
  const FlutterUnitDemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlutterUnit',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

这是应用的入口代码,创建了一个 MaterialApp 实例,并设置了主题和首页。使用了 Material 3 设计系统,提供了现代化的 UI 风格。

4.2 主页面与底部导航

dart 复制代码
class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;

  static const List<Widget> _widgetOptions = <Widget>[
    SplashScreen(),
    ComponentListScreen(),
    ComponentListScreen(), // 暂时使用同一个页面,实际应该是收藏页面
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: '首页',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: '搜索',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.star),
            label: '收藏',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.blue[600],
        unselectedItemColor: Colors.grey,
        onTap: _onItemTapped,
      ),
    );
  }
}

主页面实现了底部导航栏,包含三个导航项,分别对应首页、搜索和收藏页面。通过 setState 管理当前选中的导航项,并根据选中的索引显示对应的页面。

4.3 启动页面

dart 复制代码
class SplashScreen extends StatelessWidget {
  const SplashScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.lightBlue[50],
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // Flutter Unit 标志
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                width: 20,
                height: 40,
                color: Colors.blue,
                transform: Matrix4.rotationZ(0.3),
              ),
              const SizedBox(width: 8),
              Container(
                width: 20,
                height: 40,
                color: Colors.blue,
                transform: Matrix4.rotationZ(-0.3),
              ),
            ],
          ),
          const SizedBox(height: 40),
          // 彩色圆形图案
          Stack(
            alignment: Alignment.center,
            children: [
              SizedBox(
                width: 200,
                height: 200,
                child: CustomPaint(
                  painter: _ColorWheelPainter(),
                ),
              ),
              // 中心圆形
              Container(
                width: 60,
                height: 60,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.white,
                  border: Border.all(color: Colors.blue, width: 2),
                ),
                child: const Center(
                  child: Text(
                    'F',
                    style: TextStyle(
                      fontSize: 30,
                      fontWeight: FontWeight.bold,
                      color: Colors.blue,
                    ),
                  ),
                ),
              ),
            ],
          ),
          const SizedBox(height: 40),
          // Flutter Unit 文字
          const Text(
            'Flutter Unit',
            style: TextStyle(
              fontSize: 32,
              fontWeight: FontWeight.bold,
              color: Colors.blue,
            ),
          ),
          const SizedBox(height: 10),
          const Text(
            'Power By 张风捷特烈',
            style: TextStyle(
              fontSize: 16,
              color: Colors.grey,
            ),
          ),
        ],
      ),
    );
  }
}

启动页面实现了应用的标志和品牌信息,包括:

  • Flutter Unit 标志,使用两个旋转的蓝色矩形
  • 彩色圆形图案,使用 CustomPaint 绘制
  • 中心圆形,带有字母 'F'
  • Flutter Unit 文字和作者信息

4.4 彩色圆形图案绘制器

dart 复制代码
class _ColorWheelPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 2;

    // 绘制四个扇形
    final paint1 = Paint()..color = Colors.red;
    final paint2 = Paint()..color = Colors.blue;
    final paint3 = Paint()..color = Colors.yellow;
    final paint4 = Paint()..color = Colors.green;

    // 红色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -3 * 3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint1,
    );

    // 蓝色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint2,
    );

    // 黄色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint3,
    );

    // 绿色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      5 * 3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint4,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

彩色圆形图案绘制器使用 CustomPaint 实现,绘制了四个不同颜色的扇形,形成一个彩色的圆形图案。

4.5 组件列表页面

dart 复制代码
class ComponentListScreen extends StatefulWidget {
  const ComponentListScreen({super.key});

  @override
  State<ComponentListScreen> createState() => _ComponentListScreenState();
}

class _ComponentListScreenState extends State<ComponentListScreen> {
  int _selectedTabIndex = 0;

  final List<String> _tabs = [
    'Blue',
    'Stful',
    'Row',
    'Column',
    'Silver',
    'Other',
  ];

  final List<ComponentCard> _components = [
    ComponentCard(
      title: 'Expanded',
      description: '父类是Flexible,相当于一个类型为fill的flexible组件。可容纳孩子到...',
      rating: 5,
      color: Colors.blue[200]!,
      icon: 'Ex',
    ),
    // 其他组件...
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('FlutterUnit'),
        backgroundColor: Colors.blue[600],
      ),
      body: Column(
        children: [
          // 标签栏
          Container(
            color: Colors.white,
            padding: const EdgeInsets.symmetric(vertical: 10),
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Row(
                children: List.generate(
                  _tabs.length,
                  (index) => GestureDetector(
                    onTap: () {
                      setState(() {
                        _selectedTabIndex = index;
                      });
                    },
                    child: Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 16,
                        vertical: 8,
                      ),
                      margin: const EdgeInsets.symmetric(horizontal: 4),
                      decoration: BoxDecoration(
                        color: _selectedTabIndex == index
                            ? Colors.blue[600]
                            : Colors.grey[200],
                        borderRadius: BorderRadius.circular(16),
                      ),
                      child: Text(
                        _tabs[index],
                        style: TextStyle(
                          color: _selectedTabIndex == index
                              ? Colors.white
                              : Colors.grey[700],
                          fontWeight: _selectedTabIndex == index
                              ? FontWeight.bold
                              : FontWeight.normal,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
          // 组件列表
          Expanded(
            child: GridView.builder(
              padding: const EdgeInsets.all(10),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                crossAxisSpacing: 10,
                mainAxisSpacing: 10,
                childAspectRatio: 0.75,
              ),
              itemCount: _components.length,
              itemBuilder: (context, index) {
                final component = _components[index];
                return _buildComponentCard(component);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildComponentCard(ComponentCard component) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [
          BoxShadow(
            color: Colors.grey.withOpacity(0.2),
            spreadRadius: 2,
            blurRadius: 4,
            offset: const Offset(0, 2),
          ),
        ],
      ),
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 组件图标和名称
            Row(
              children: [
                Container(
                  width: 40,
                  height: 40,
                  decoration: BoxDecoration(
                    color: component.color,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Center(
                    child: Text(
                      component.icon,
                      style: const TextStyle(
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: Text(
                    component.title,
                    style: const TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 16,
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 10),
            // 组件描述
            Text(
              component.description,
              style: const TextStyle(
                fontSize: 14,
                color: Colors.grey,
              ),
              maxLines: 3,
              overflow: TextOverflow.ellipsis,
            ),
            const SizedBox(height: 10),
            // 星级评分
            Row(
              children: List.generate(
                5,
                (index) => Icon(
                  index < component.rating
                      ? Icons.star
                      : Icons.star_border,
                  size: 14,
                  color: Colors.amber,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

组件列表页面实现了:

  • 蓝色的应用栏,显示 "FlutterUnit" 标题
  • 可横向滚动的标签栏,包含不同类型的组件分类
  • 网格布局的组件卡片,每个卡片包含组件图标、名称、描述和星级评分

4.6 组件卡片数据类

dart 复制代码
class ComponentCard {
  final String title;
  final String description;
  final int rating;
  final Color color;
  final String icon;

  ComponentCard({
    required this.title,
    required this.description,
    required this.rating,
    required this.color,
    required this.icon,
  });
}

组件卡片数据类定义了组件卡片的属性,包括标题、描述、评分、颜色和图标。

5. 技术亮点与创新

5.1 UI 还原度

  • 高度还原:成功还原了 FlutterUnit 应用的核心 UI 效果,包括启动页面、组件列表页面和底部导航栏
  • 细节处理:精心处理了应用标志、彩色圆形图案、组件卡片等细节,确保视觉效果与原应用一致
  • 响应式设计:使用了响应式布局,确保应用在不同屏幕尺寸上都能正常显示

5.2 技术实现

  • 自定义绘制:使用 CustomPaint 实现了彩色圆形图案的绘制,展示了 Flutter 的自定义绘制能力
  • 布局优化:使用 GridView 实现了组件卡片的网格布局,提高了页面的加载和滚动性能
  • 状态管理:使用 setState 进行状态管理,代码简洁易懂,适合中小型应用

5.3 鸿蒙平台适配

  • 兼容性:确保应用在鸿蒙平台上的正常运行,所有组件都能正确显示和交互
  • 性能优化:针对鸿蒙平台的特性进行了性能优化,确保应用运行流畅
  • 用户体验:保持了与原应用一致的用户体验,确保用户可以无缝切换使用

5.4 用户交互

  • 标签栏交互:实现了标签栏的点击切换功能,用户可以方便地浏览不同类型的组件
  • 底部导航:实现了底部导航栏的切换功能,用户可以在不同页面之间切换
  • 组件卡片:设计了美观的组件卡片,提供了清晰的组件信息展示

6. 应用场景与扩展

6.1 应用场景

  • 学习工具:帮助 Flutter 开发者快速了解和学习各种组件的使用方法
  • 参考手册:作为 Flutter 组件的参考手册,随时查阅组件的用法和效果
  • 教学演示:在 Flutter 教学中作为演示工具,展示组件的使用方法和效果
  • 设计参考:作为 UI 设计的参考,了解如何构建美观的 Flutter 应用

6.2 扩展方向

  • 更多组件:添加更多 Flutter 组件的演示,包括动画组件、自定义组件等
  • 组件详情:添加组件详情页面,提供更详细的组件使用方法和代码示例
  • 搜索功能:添加组件搜索功能,方便用户快速找到需要的组件
  • 收藏功能:实现真正的收藏页面,允许用户收藏常用组件
  • 代码导出:添加代码导出功能,用户可以直接复制组件的代码到自己的项目中

7. 代码优化建议

7.1 性能优化

  1. 使用 const 构造函数:对于不变的组件,使用 const 构造函数可以减少不必要的重建
  2. 使用 const 变量:对于不变的变量,使用 const 关键字可以提高性能
  3. 避免不必要的 setState:只在必要时调用 setState,避免过度更新
  4. 使用 ListView.builder:对于长列表,使用 ListView.builder 可以提高性能
  5. 使用 RepaintBoundary:对于复杂的组件,使用 RepaintBoundary 可以减少重绘范围

7.2 代码结构优化

  1. 组件拆分:将大组件拆分为小组件,提高代码的可读性和可维护性
  2. 提取常量:将重复使用的值提取为常量,便于统一管理和修改
  3. 使用命名参数:使用命名参数可以提高代码的可读性
  4. 添加注释:为关键代码添加注释,提高代码的可维护性
  5. 使用枚举:对于有限的选项,使用枚举可以提高代码的可读性和类型安全性

7.3 用户体验优化

  1. 添加过渡动画:在页面切换和状态变化时添加过渡动画,提高用户体验
  2. 添加加载状态:在加载数据时添加加载状态,提高用户体验
  3. 添加错误处理:添加错误处理,确保应用在遇到错误时能够优雅地处理
  4. 添加空状态:添加空状态提示,提高用户体验
  5. 添加手势反馈:为可交互组件添加手势反馈,提高用户体验

7.4 功能优化

  1. 添加组件分类:进一步细化组件分类,便于用户查找
  2. 添加组件搜索:添加组件搜索功能,方便用户快速找到需要的组件
  3. 添加代码复制:添加代码复制功能,方便用户复制组件代码
  4. 添加组件收藏:添加组件收藏功能,方便用户保存常用组件
  5. 添加组件评论:添加组件评论功能,方便用户交流和分享使用经验

8. 测试与调试

8.1 测试策略

  1. 单元测试:对关键函数和方法进行单元测试,确保其功能正确
  2. Widget 测试:对关键组件进行 Widget 测试,确保其显示和交互正确
  3. 集成测试:对整个应用进行集成测试,确保各组件之间的交互正确
  4. 性能测试:对应用进行性能测试,确保其性能符合要求
  5. 跨平台测试:在不同平台上测试应用,确保其在所有平台上的表现一致

8.2 调试技巧

  1. 使用 print 语句:在关键位置添加 print 语句,输出变量值和执行流程
  2. 使用 Flutter DevTools:使用 Flutter DevTools 进行调试,查看应用的布局、性能和状态
  3. 使用断点:在关键位置设置断点,查看变量值和执行流程
  4. 使用热重载:使用热重载功能,快速查看代码修改的效果
  5. 使用模拟器:在不同的模拟器上测试应用,确保其在不同设备上的表现一致

8.3 常见问题及解决方案

问题 原因 解决方案
布局溢出 组件尺寸超过屏幕尺寸 使用 SingleChildScrollView 包裹内容,或使用 Expanded 组件
状态更新不及时 setState 调用时机不正确 确保在正确的时机调用 setState,避免在 build 方法中调用
性能问题 组件重建过于频繁 使用 const 构造函数,避免不必要的 setState,使用 ListView.builder 等高效组件
导航错误 导航逻辑不正确 确保导航逻辑正确,使用正确的导航方法
跨平台兼容性问题 平台差异 使用 Flutter 内置的跨平台组件,避免使用平台特定的 API
图片资源错误 图片资源不存在 使用默认资源或占位符,确保应用在缺少资源时仍能正常运行

9. 总结与展望

9.1 项目成果

FlutterUnit 组件百科适配项目成功实现了以下功能:

  • 高度还原了 FlutterUnit 应用的核心 UI 效果,包括启动页面、组件列表页面和底部导航栏
  • 实现了组件卡片的网格布局,展示了多个 Flutter 组件的信息
  • 确保了应用在鸿蒙平台上的正常运行,所有组件都能正确显示和交互
  • 提供了清晰的组件信息展示,包括组件名称、描述和星级评分
  • 实现了标签栏和底部导航栏的交互功能,提高了用户体验

9.2 技术价值

  • 学习价值:为 Flutter 开发者提供了一个学习组件使用方法的平台
  • 参考价值:作为 Flutter 组件的参考手册,随时查阅组件的用法和效果
  • 教学价值:在 Flutter 教学中作为演示工具,展示组件的使用方法和效果
  • 开发价值:为开发者提供了组件使用的最佳实践,加速开发过程
  • 适配价值:展示了如何将 Flutter 应用适配到鸿蒙平台,为跨平台开发提供参考

9.3 未来展望

  • 扩展组件库:添加更多 Flutter 组件的演示,包括动画组件、自定义组件等
  • 增强功能:添加组件详情页面、搜索功能、收藏功能等增强功能
  • 优化性能:进一步优化应用性能,提高用户体验
  • 社区贡献:将项目开源,邀请社区贡献,共同完善和扩展项目
  • 多平台支持:确保在更多平台上的兼容性,包括鸿蒙、iOS、Android、Web 等
  • 国际化:添加多语言支持,使应用能够服务于更多用户

9.4 结语

FlutterUnit 组件百科适配项目是一个功能完整、界面美观、交互友好的组件百科全书,为 Flutter 开发者提供了一个学习和参考的平台。通过本项目,开发者可以快速了解和掌握 Flutter 中各种组件的使用方法,提高开发效率和代码质量。

同时,本项目也展示了如何将 Flutter 应用适配到鸿蒙平台,为跨平台开发提供了参考。未来,我们将继续完善和扩展项目,添加更多组件和功能,为 Flutter 社区做出更大的贡献。

10. 附录

10.1 完整代码

dart 复制代码
import 'package:flutter/material.dart';

void main() {
  runApp(const FlutterUnitDemoApp());
}

class FlutterUnitDemoApp extends StatelessWidget {
  const FlutterUnitDemoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlutterUnit',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0;

  static const List<Widget> _widgetOptions = <Widget>[
    SplashScreen(),
    ComponentListScreen(),
    ComponentListScreen(), // 暂时使用同一个页面,实际应该是收藏页面
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: '首页',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: '搜索',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.star),
            label: '收藏',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.blue[600],
        unselectedItemColor: Colors.grey,
        onTap: _onItemTapped,
      ),
    );
  }
}

// 启动页面
class SplashScreen extends StatelessWidget {
  const SplashScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.lightBlue[50],
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // Flutter Unit 标志
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                width: 20,
                height: 40,
                color: Colors.blue,
                transform: Matrix4.rotationZ(0.3),
              ),
              const SizedBox(width: 8),
              Container(
                width: 20,
                height: 40,
                color: Colors.blue,
                transform: Matrix4.rotationZ(-0.3),
              ),
            ],
          ),
          const SizedBox(height: 40),
          // 彩色圆形图案
          Stack(
            alignment: Alignment.center,
            children: [
              SizedBox(
                width: 200,
                height: 200,
                child: CustomPaint(
                  painter: _ColorWheelPainter(),
                ),
              ),
              // 中心圆形
              Container(
                width: 60,
                height: 60,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.white,
                  border: Border.all(color: Colors.blue, width: 2),
                ),
                child: const Center(
                  child: Text(
                    'F',
                    style: TextStyle(
                      fontSize: 30,
                      fontWeight: FontWeight.bold,
                      color: Colors.blue,
                    ),
                  ),
                ),
              ),
            ],
          ),
          const SizedBox(height: 40),
          // Flutter Unit 文字
          const Text(
            'Flutter Unit',
            style: TextStyle(
              fontSize: 32,
              fontWeight: FontWeight.bold,
              color: Colors.blue,
            ),
          ),
          const SizedBox(height: 10),
          const Text(
            'Power By 张风捷特烈',
            style: TextStyle(
              fontSize: 16,
              color: Colors.grey,
            ),
          ),
        ],
      ),
    );
  }
}

// 彩色圆形图案绘制器
class _ColorWheelPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 2;

    // 绘制四个扇形
    final paint1 = Paint()..color = Colors.red;
    final paint2 = Paint()..color = Colors.blue;
    final paint3 = Paint()..color = Colors.yellow;
    final paint4 = Paint()..color = Colors.green;

    // 红色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -3 * 3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint1,
    );

    // 蓝色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint2,
    );

    // 黄色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint3,
    );

    // 绿色扇形
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      5 * 3.14159265359 / 4,
      3.14159265359 / 2,
      true,
      paint4,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

// 组件列表页面
class ComponentListScreen extends StatefulWidget {
  const ComponentListScreen({super.key});

  @override
  State<ComponentListScreen> createState() => _ComponentListScreenState();
}

class _ComponentListScreenState extends State<ComponentListScreen> {
  int _selectedTabIndex = 0;

  final List<String> _tabs = [
    'Blue',
    'Stful',
    'Row',
    'Column',
    'Silver',
    'Other',
  ];

  final List<ComponentCard> _components = [
    ComponentCard(
      title: 'Expanded',
      description: '父类是Flexible,相当于一个类型为fill的flexible组件。可容纳孩子到...',
      rating: 5,
      color: Colors.blue[200]!,
      icon: 'Ex',
    ),
    ComponentCard(
      title: 'MediaQuery',
      description: '可通过MediaQuery的某个获取屏幕尺寸、设备密度、文字缩放比例、边距...',
      rating: 4,
      color: Colors.green[200]!,
      icon: 'Me',
    ),
    ComponentCard(
      title: 'Positioned',
      description: '只能用于Stack中,可以指定左上右下的距离来对单个组件进行位置精确定位。',
      rating: 4,
      color: Colors.orange[200]!,
      icon: 'Po',
    ),
    ComponentCard(
      title: 'Flexible',
      description: '只能用于只能用于Row、Column和Flexible布局中,可使孩子利用剩余空间。',
      rating: 4,
      color: Colors.purple[200]!,
      icon: 'Fl',
    ),
    ComponentCard(
      title: 'ScrollConfiguration',
      description: '需要包裹一个可滑动的组件,并通过behavior属性控制滑动时的效果,可以...',
      rating: 4,
      color: Colors.yellow[200]!,
      icon: 'Sc',
    ),
    ComponentCard(
      title: 'Transform',
      description: '可容纳一个子组件,可以通过一个4x4的变换矩阵对子组件进行变换。',
      rating: 5,
      color: Colors.purple[200]!,
      icon: 'Tr',
    ),
    ComponentCard(
      title: 'OverflowBox',
      description: '可容纳一个子组件,且子组件允许溢出父组件区域,可以指定宽高的最大...',
      rating: 4,
      color: Colors.blue[200]!,
      icon: 'Ov',
    ),
    ComponentCard(
      title: 'FittedBox',
      description: '可容纳一个子组件,使用fit属性决定子组件区域相当于父组件的适应模式。',
      rating: 4,
      color: Colors.green[200]!,
      icon: 'Fi',
    ),
    ComponentCard(
      title: 'ShaderMask',
      description: '可容纳一个孩子,并通过着色器来对孩子进行着色,可指定着色模式,通...',
      rating: 4,
      color: Colors.orange[200]!,
      icon: 'Sh',
    ),
    ComponentCard(
      title: 'BackdropFilter',
      description: '可容纳一个孩子,并将背景进行模糊处理,可以指定模糊的程度和模式...',
      rating: 4,
      color: Colors.purple[200]!,
      icon: 'Ba',
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('FlutterUnit'),
        backgroundColor: Colors.blue[600],
      ),
      body: Column(
        children: [
          // 标签栏
          Container(
            color: Colors.white,
            padding: const EdgeInsets.symmetric(vertical: 10),
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Row(
                children: List.generate(
                  _tabs.length,
                  (index) => GestureDetector(
                    onTap: () {
                      setState(() {
                        _selectedTabIndex = index;
                      });
                    },
                    child: Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 16,
                        vertical: 8,
                      ),
                      margin: const EdgeInsets.symmetric(horizontal: 4),
                      decoration: BoxDecoration(
                        color: _selectedTabIndex == index
                            ? Colors.blue[600]
                            : Colors.grey[200],
                        borderRadius: BorderRadius.circular(16),
                      ),
                      child: Text(
                        _tabs[index],
                        style: TextStyle(
                          color: _selectedTabIndex == index
                              ? Colors.white
                              : Colors.grey[700],
                          fontWeight: _selectedTabIndex == index
                              ? FontWeight.bold
                              : FontWeight.normal,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
          // 组件列表
          Expanded(
            child: GridView.builder(
              padding: const EdgeInsets.all(10),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                crossAxisSpacing: 10,
                mainAxisSpacing: 10,
                childAspectRatio: 0.75,
              ),
              itemCount: _components.length,
              itemBuilder: (context, index) {
                final component = _components[index];
                return _buildComponentCard(component);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildComponentCard(ComponentCard component) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        boxShadow: [
          BoxShadow(
            color: Colors.grey.withOpacity(0.2),
            spreadRadius: 2,
            blurRadius: 4,
            offset: const Offset(0, 2),
          ),
        ],
      ),
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 组件图标和名称
            Row(
              children: [
                Container(
                  width: 40,
                  height: 40,
                  decoration: BoxDecoration(
                    color: component.color,
                    borderRadius: BorderRadius.circular(8),
                  ),
                  child: Center(
                    child: Text(
                      component.icon,
                      style: const TextStyle(
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
                const SizedBox(width: 10),
                Expanded(
                  child: Text(
                    component.title,
                    style: const TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 16,
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 10),
            // 组件描述
            Text(
              component.description,
              style: const TextStyle(
                fontSize: 14,
                color: Colors.grey,
              ),
              maxLines: 3,
              overflow: TextOverflow.ellipsis,
            ),
            const SizedBox(height: 10),
            // 星级评分
            Row(
              children: List.generate(
                5,
                (index) => Icon(
                  index < component.rating
                      ? Icons.star
                      : Icons.star_border,
                  size: 14,
                  color: Colors.amber,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// 组件卡片数据类
class ComponentCard {
  final String title;
  final String description;
  final int rating;
  final Color color;
  final String icon;

  ComponentCard({
    required this.title,
    required this.description,
    required this.rating,
    required this.color,
    required this.icon,
  });
}

10.2 依赖项

依赖项 版本 用途
flutter 3.35.7 核心框架
material.dart - Material 设计组件库

10.3 运行环境

环境 版本
Flutter 3.35.7
Dart 3.2.0
鸿蒙 SDK 5.0.0
Android SDK 33.0.0
iOS SDK 16.0

10.4 参考资源

相关推荐
前端不太难2 小时前
一天做出:鸿蒙 + AI 游戏 Demo
人工智能·游戏·harmonyos
木斯佳5 小时前
HarmonyOS 6实战:AI Action富媒体卡片迭代——实现快照分享
人工智能·harmonyos·媒体
2301_764441338 小时前
LISA时空跃迁分析,地理时空分析
数据结构·python·算法
东北洗浴王子讲AI8 小时前
GPT-5.4辅助算法设计与优化:从理论到实践的系统方法
人工智能·gpt·算法·chatgpt
Billlly9 小时前
ABC 453 个人题解
算法·题解·atcoder
玉树临风ives9 小时前
atcoder ABC 452 题解
数据结构·算法
feifeigo12310 小时前
基于马尔可夫随机场模型的SAR图像变化检测源码实现
算法
fengfuyao98510 小时前
基于STM32的4轴步进电机加减速控制工程源码(梯形加减速算法)
网络·stm32·算法
不爱吃糖的程序媛10 小时前
适配鸿蒙PC sha_ohos.patch 补丁文件详解
华为·harmonyos