一直有群友问我推荐个 UI 组件库啥的,其实不一定适合你,做移动APP还是要自己包装组件库才好用,今天聊下为什么。

Flutter 是否需要 UI 组件库?

Flutter UI 组件库

视频

前言

原文 如何满足 Flutter 项目的复杂 UI 需求?

一直有群友问我推荐个 UI 组件库啥的,其实不一定适合你,做移动APP还是要自己包装组件库才好用,今天聊下为什么。

常见组件库

UI 库汇总

https://flutter.ducafecat.com/pubs/widget-library-ui-framework-packages

组件库

这些组件看起来很丰富很漂亮,但是有一个最大的问题就是定制起来不方便,如果你对UI没有什么要求,可以选一套漂亮的用上。

工作中场景

我们实际工作中都是定制交互界面,在那么多APP中你想突出,UI界面还是要的。

健身

健身

健康

健康

金融

金融

音乐播放

音乐播放

电商

电商

健身

健身

所以你需要自己整理一套组件库

UI 需要解决的问题

猫哥封装了一个核心组件 https://pub.dev/packages/ducafe_ui_core ,有兴趣可以看看。

下面聊下 UI 要面对的问题。

减少嵌套

采用默认嵌套写法代码量大,层次深,不方便阅读、长期维护,所以猫哥采用扩展方式。

默认写法

  // 商品标题
  Widget _buildTitle(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        // 金额、打分、喜欢
        Row(
          children: [
            // 金额
            Expanded(
              child: Text(
                "\$${controller.product?.price ?? 0}",
                style: TextStyle(fontSize: 24), // 根据需要设置字体大小
              ),
            ),
            // 打分
            Row(
              children: [
                Icon(
                  Icons.star,
                  size: 20,
                  color: context.colors.scheme.primary,
                ),
                SizedBox(width: 4), // 设置图标和文本之间的间距
                Text(
                  "4.5",
                  style: TextStyle(color: context.colors.scheme.primary),
                ),
              ],
            ),
            SizedBox(width: 16), // 设置图标和文本之间的间距
            // 喜欢
            Row(
              children: [
                Icon(
                  Icons.favorite,
                  size: 20,
                  color: context.colors.scheme.primary,
                ),
                SizedBox(width: 4), // 设置图标和文本之间的间距
                Text(
                  "100+",
                  style: TextStyle(color: context.colors.scheme.primary),
                ),
              ],
            ),
          ],
        ),

        // 次标题
        Text(
          controller.product?.shortDescription?.clearHtml ?? "-",
          style: TextStyle(fontSize: 16), // 根据需要设置字体大小
        ),
      ],
    ).padding(EdgeInsets.all(16)); // 使用原生的 Padding
  }

嵌套后代码

  // 商品标题
  Widget _buildTitle(BuildContext context) {
    return <Widget>[
      // 金额、打分、喜欢
      <Widget>[
        // 金额
        TextWidget.h3(
          "\$${controller.product?.price ?? 0}",
        ).expanded(),
        // 打分
        IconWidget.icon(
          Icons.star,
          text: "4.5",
          size: 20,
          color: context.colors.scheme.primary,
        ).paddingRight(AppSpace.iconTextMedium),
        // 喜欢
        IconWidget.icon(
          Icons.favorite,
          text: "100+",
          size: 20,
          color: context.colors.scheme.primary,
        ),
      ].toRow(),

      // 次标题
      TextWidget.label(
        controller.product?.shortDescription?.clearHtml ?? "-",
      ),
    ]
        .toColumn(
          // 左对齐
          crossAxisAlignment: CrossAxisAlignment.start,
          // 垂直间距
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
        )
        .paddingAll(AppSpace.page);
  }

其实这事和 html + css 一回事。

基础组件抽取

源码的方式组织你的组件,我抽取了一个代码模版可以复用,有项目定制改改。

项目模版

这些基础组件应该包含 文本、图片、输入框、表单、卡片、按钮 ...

组件抽取

屏幕尺寸适配

设计稿出样后,程序需要在各种设备屏幕上运行。

我们给出的方案是按长宽比例计算(设计稿尺寸 : 设备屏幕尺寸)。

多设备屏幕

程序启动时初始尺寸比例

import 'package:ducafe_ui_core/ducafe_ui_core.dart';

void main() {
  runApp(
    ScreenUtilInit(
      designSize: const Size(360, 690),
      builder: (context, child) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: child,
        );
      },
      child: const HomePage(),
    ),
  );
}

ScreenUtilInit 包裹 MaterialApp 进行初始比例。

运行时视图 view 计算

  // Tab 栏位按钮
  Widget _buildTabBarItem(BuildContext context, String textString, int index) {
    return ButtonWidget.outline(
      ...
      
    ).tight(
      width: 100.w,
      height: 35.h,
    );
  }

.w .h 扩展就是动态依据比例计算。

主题样式

  • 明暗色
  • 自定义主题色
  • 组件样式定制
  • ......

其实类似的细节还有很多,就不在本文中一一罗列了。

欢迎看我的 woo2025 课程。

代码

https://pub.dev/packages/ducafe_ui_core

https://github.com/ducafecat/flutter_package_ducafe_ui_core

小结

本文深入探讨了 Flutter UI 组件库的必要性,分析了在实际工作中遇到的 UI 要求和解决方案。我们讨论了如何通过减少嵌套、开发通用和业务组件、以及实现屏幕和颜色适配等策略,来提升开发效率。通过对猫哥封装的 UI 组件库的介绍,本文为开发者提供了实用的参考和指导,帮助他们在 Flutter 开发中更好地应对 UI 挑战。

感谢阅读本文

如果有什么建议,请在评论中让我知道。我很乐意改进。


猫哥 APP

flutter 学习路径


© 猫哥 ducafecat.com

end