Flutter 小白入门教程Flutter 小白入门教程
首页
学习指南
项目实战
Flutter 官网
编程指南
首页
学习指南
项目实战
Flutter 官网
编程指南
  • 入门基础

    • 📚 基础教程
    • 第1章 - 认识 Flutter
    • 第2章 - 环境搭建
    • 第3章 - Dart 语言基础
    • 第4章 - 第一个 Flutter 应用
    • 第5章 - Widget 基础
    • 第6章 - 布局系统
    • 第7章 - 状态管理入门
    • 第8章 - 页面导航
    • 第9章 - 资源管理
  • 进阶开发

    • 第10章 - 网络请求
    • 第11章 - 本地存储
    • 第12章 - 对话框与反馈
    • 第13章 - 列表进阶
    • 第14章 - 主题定制
    • 第15章 - 状态管理进阶
    • 第16章 - 动画入门
    • 第17章 - 常用第三方包
  • 调试与发布

    • 第18章 - 调试与性能优化
    • 第19章 - 打包与发布
  • 附录

    • 附录A - UI 框架与组件库推荐
    • 附录B - 项目结构最佳实践
    • 附录C - 国际化配置
    • 附录D - 权限处理

附录A - UI 框架与组件库推荐

嗨,朋友!我是长安。

作为 Flutter 小白,你可能会困惑:如何快速做出漂亮的界面? 答案就是:善用现成的 UI 框架和组件库!

这一章,我会推荐一些优秀的 UI 资源,让你的 App 瞬间变得高大上!

🎨 Flutter 内置 Material 组件

Flutter 自带了丰富的 Material Design 组件,先把这些用熟练!

Material 3 新特性

Material 3 是最新的设计规范,Flutter 3.0+ 已全面支持。

MaterialApp(
  theme: ThemeData(
    useMaterial3: true,  // 启用 Material 3
    colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
  ),
  home: const HomePage(),
)

常用 Material 组件一览

// 按钮系列
ElevatedButton(onPressed: () {}, child: const Text('凸起按钮'))
FilledButton(onPressed: () {}, child: const Text('填充按钮'))  // M3 新增
FilledButton.tonal(onPressed: () {}, child: const Text('色调按钮'))  // M3 新增
OutlinedButton(onPressed: () {}, child: const Text('轮廓按钮'))
TextButton(onPressed: () {}, child: const Text('文字按钮'))
IconButton(onPressed: () {}, icon: const Icon(Icons.add))
FloatingActionButton(onPressed: () {}, child: const Icon(Icons.add))
FloatingActionButton.extended(  // M3 推荐
  onPressed: () {},
  icon: const Icon(Icons.add),
  label: const Text('新建'),
)

// 输入框
TextField(decoration: const InputDecoration(labelText: '用户名'))
SearchBar(hintText: '搜索...')  // M3 新增

// 卡片与容器
Card(child: ...)
Card.filled(child: ...)   // M3 新增
Card.outlined(child: ...) // M3 新增

// 导航
NavigationBar(...)        // M3 底部导航
NavigationRail(...)       // M3 侧边导航
NavigationDrawer(...)     // M3 抽屉导航

// 提示与反馈
SnackBar(content: Text('提示'))
AlertDialog(title: Text('标题'), content: Text('内容'))
BottomSheet(builder: ...)

// 选择器
Checkbox(value: true, onChanged: (v) {})
Switch(value: true, onChanged: (v) {})
Radio(value: 1, groupValue: 1, onChanged: (v) {})
Slider(value: 0.5, onChanged: (v) {})
DropdownMenu(...)         // M3 新增
SegmentedButton(...)      // M3 新增

// 进度指示
CircularProgressIndicator()
LinearProgressIndicator()

// 标签
Chip(label: Text('标签'))
FilterChip(label: Text('筛选'), selected: true, onSelected: (v) {})
InputChip(label: Text('输入'))
ActionChip(label: Text('操作'), onPressed: () {})

Material 3 配色示例

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 使用种子色自动生成配色方案
    final colorScheme = ColorScheme.fromSeed(
      seedColor: const Color(0xFF6750A4),  // 品牌色
      brightness: Brightness.light,
    );

    return MaterialApp(
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: colorScheme,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Material 3'),
          backgroundColor: colorScheme.primaryContainer,
          foregroundColor: colorScheme.onPrimaryContainer,
        ),
        body: Center(
          child: FilledButton(
            onPressed: () {},
            child: const Text('Material 3 按钮'),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {},
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

📦 第三方 UI 框架

GetWidget(1000+ 组件)

功能最全面的 Flutter UI 库,包含 1000+ 预构建组件。

dependencies:
  getwidget: ^4.0.0
import 'package:getwidget/getwidget.dart';

// 按钮
GFButton(
  onPressed: () {},
  text: '按钮',
  type: GFButtonType.solid,
  shape: GFButtonShape.pills,
)

// 头像
GFAvatar(
  backgroundImage: NetworkImage('https://example.com/avatar.jpg'),
  shape: GFAvatarShape.circle,
  size: GFSize.LARGE,
)

// 徽章
GFBadge(
  text: '99+',
  color: GFColors.DANGER,
  shape: GFBadgeShape.circle,
)

// 卡片
GFCard(
  boxFit: BoxFit.cover,
  image: Image.network('https://example.com/image.jpg'),
  title: GFListTile(
    avatar: GFAvatar(backgroundImage: NetworkImage('url')),
    title: const Text('标题'),
    subtitle: const Text('副标题'),
  ),
  content: const Text('卡片内容...'),
  buttonBar: GFButtonBar(
    children: [
      GFButton(onPressed: () {}, text: '点赞'),
      GFButton(onPressed: () {}, text: '分享'),
    ],
  ),
)

// 轮播图
GFCarousel(
  items: imageList.map((url) {
    return Container(
      margin: const EdgeInsets.all(8),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(8),
        child: Image.network(url, fit: BoxFit.cover),
      ),
    );
  }).toList(),
  autoPlay: true,
  pagination: true,
)

// 评分
GFRating(
  value: 3.5,
  onChanged: (value) {},
  size: GFSize.MEDIUM,
  filledIcon: Icon(Icons.star, color: Colors.amber),
  halfFilledIcon: Icon(Icons.star_half, color: Colors.amber),
  defaultIcon: Icon(Icons.star_border, color: Colors.amber),
)

// 进度条
GFProgressBar(
  percentage: 0.7,
  lineHeight: 20,
  animation: true,
  animationDuration: 1000,
  backgroundColor: Colors.grey[200]!,
  progressBarColor: GFColors.SUCCESS,
)

// Toast
GFToast.showToast('操作成功', context);

// 骨架屏
GFShimmer(
  child: Container(
    height: 200,
    width: double.infinity,
    color: Colors.white,
  ),
)

GetWidget 组件分类:

分类组件
基础Button, Avatar, Badge, Image, Card
表单TextField, Checkbox, Radio, Switch, Rating
导航AppBar, TabBar, BottomNav, Drawer
反馈Toast, Loader, Shimmer, Progress
展示Carousel, Accordion, ListTile, Typography
布局Container, Grid, Tile, Sticky Header

flutter_neumorphic(新拟态风格)

独特的新拟态 UI 风格。

dependencies:
  flutter_neumorphic: ^3.2.0
import 'package:flutter_neumorphic/flutter_neumorphic.dart';

// 使用 NeumorphicApp
NeumorphicApp(
  title: 'Neumorphic App',
  themeMode: ThemeMode.light,
  theme: const NeumorphicThemeData(
    baseColor: Color(0xFFE0E0E0),
    lightSource: LightSource.topLeft,
    depth: 10,
  ),
  home: HomePage(),
)

// 新拟态按钮
NeumorphicButton(
  onPressed: () {},
  style: const NeumorphicStyle(
    shape: NeumorphicShape.flat,
    boxShape: NeumorphicBoxShape.roundRect(
      BorderRadius.all(Radius.circular(12)),
    ),
  ),
  child: const Text('按钮'),
)

// 新拟态容器
Neumorphic(
  style: const NeumorphicStyle(
    depth: 8,
    intensity: 0.65,
  ),
  child: Container(
    width: 200,
    height: 100,
    child: const Center(child: Text('新拟态卡片')),
  ),
)

// 新拟态图标
NeumorphicIcon(
  Icons.favorite,
  size: 60,
  style: const NeumorphicStyle(color: Colors.red),
)

// 新拟态进度条
NeumorphicProgress(
  percent: 0.7,
  height: 20,
  style: const ProgressStyle(
    accent: Colors.blue,
    variant: Colors.blueGrey,
  ),
)

fluent_ui(微软 Fluent 风格)

Windows 风格的 UI 组件。

dependencies:
  fluent_ui: ^4.8.5
import 'package:fluent_ui/fluent_ui.dart';

// 使用 FluentApp
FluentApp(
  title: 'Fluent App',
  theme: FluentThemeData(
    accentColor: Colors.blue,
    brightness: Brightness.light,
  ),
  home: const HomePage(),
)

// Fluent 按钮
FilledButton(
  child: const Text('填充按钮'),
  onPressed: () {},
)

Button(
  child: const Text('普通按钮'),
  onPressed: () {},
)

// 导航视图
NavigationView(
  appBar: const NavigationAppBar(
    title: Text('Fluent App'),
  ),
  pane: NavigationPane(
    selected: selectedIndex,
    onChanged: (index) => setState(() => selectedIndex = index),
    displayMode: PaneDisplayMode.auto,
    items: [
      PaneItem(
        icon: const Icon(FluentIcons.home),
        title: const Text('首页'),
        body: const HomePage(),
      ),
      PaneItem(
        icon: const Icon(FluentIcons.settings),
        title: const Text('设置'),
        body: const SettingsPage(),
      ),
    ],
  ),
)

// 信息栏
InfoBar(
  title: const Text('提示'),
  content: const Text('这是一条提示信息'),
  severity: InfoBarSeverity.info,  // info, warning, error, success
  onClose: () {},
)

macos_ui(苹果 macOS 风格)

macOS 风格的 UI 组件,适合开发 macOS 应用。

dependencies:
  macos_ui: ^2.0.5
import 'package:macos_ui/macos_ui.dart';

// 使用 MacosApp
MacosApp(
  title: 'macOS App',
  theme: MacosThemeData.light(),
  darkTheme: MacosThemeData.dark(),
  home: const MainPage(),
)

// macOS 窗口
MacosWindow(
  sidebar: Sidebar(
    builder: (context, scrollController) {
      return SidebarItems(
        items: [
          SidebarItem(
            leading: const MacosIcon(CupertinoIcons.home),
            label: const Text('首页'),
          ),
          SidebarItem(
            leading: const MacosIcon(CupertinoIcons.settings),
            label: const Text('设置'),
          ),
        ],
        currentIndex: selectedIndex,
        onChanged: (index) => setState(() => selectedIndex = index),
      );
    },
    minWidth: 200,
  ),
  child: ContentArea(
    builder: (context, scrollController) {
      return pages[selectedIndex];
    },
  ),
)

// macOS 按钮
PushButton(
  buttonSize: ButtonSize.large,
  child: const Text('按钮'),
  onPressed: () {},
)

📊 图表库

fl_chart(推荐)

功能强大、高度可定制的图表库。

dependencies:
  fl_chart: ^0.66.2
import 'package:fl_chart/fl_chart.dart';

// 折线图
LineChart(
  LineChartData(
    gridData: const FlGridData(show: true),
    titlesData: const FlTitlesData(show: true),
    borderData: FlBorderData(show: true),
    lineBarsData: [
      LineChartBarData(
        spots: const [
          FlSpot(0, 3),
          FlSpot(1, 1),
          FlSpot(2, 4),
          FlSpot(3, 2),
          FlSpot(4, 5),
        ],
        isCurved: true,
        color: Colors.blue,
        barWidth: 3,
        dotData: const FlDotData(show: true),
        belowBarData: BarAreaData(
          show: true,
          color: Colors.blue.withOpacity(0.3),
        ),
      ),
    ],
  ),
)

// 柱状图
BarChart(
  BarChartData(
    alignment: BarChartAlignment.spaceAround,
    maxY: 20,
    barGroups: [
      BarChartGroupData(x: 0, barRods: [
        BarChartRodData(toY: 8, color: Colors.blue),
      ]),
      BarChartGroupData(x: 1, barRods: [
        BarChartRodData(toY: 12, color: Colors.blue),
      ]),
      BarChartGroupData(x: 2, barRods: [
        BarChartRodData(toY: 6, color: Colors.blue),
      ]),
      BarChartGroupData(x: 3, barRods: [
        BarChartRodData(toY: 15, color: Colors.blue),
      ]),
    ],
  ),
)

// 饼图
PieChart(
  PieChartData(
    sections: [
      PieChartSectionData(
        value: 40,
        title: '40%',
        color: Colors.blue,
        radius: 50,
      ),
      PieChartSectionData(
        value: 30,
        title: '30%',
        color: Colors.green,
        radius: 50,
      ),
      PieChartSectionData(
        value: 30,
        title: '30%',
        color: Colors.orange,
        radius: 50,
      ),
    ],
    centerSpaceRadius: 40,
  ),
)

// 雷达图
RadarChart(
  RadarChartData(
    radarShape: RadarShape.polygon,
    tickCount: 5,
    ticksTextStyle: const TextStyle(color: Colors.transparent),
    radarBorderData: const BorderSide(color: Colors.grey),
    dataSets: [
      RadarDataSet(
        fillColor: Colors.blue.withOpacity(0.3),
        borderColor: Colors.blue,
        dataEntries: const [
          RadarEntry(value: 4),
          RadarEntry(value: 3),
          RadarEntry(value: 5),
          RadarEntry(value: 2),
          RadarEntry(value: 4),
        ],
      ),
    ],
  ),
)

syncfusion_flutter_charts(企业级)

Syncfusion 出品,功能非常全面(社区版免费)。

dependencies:
  syncfusion_flutter_charts: ^24.2.7
import 'package:syncfusion_flutter_charts/charts.dart';

// 折线图
SfCartesianChart(
  primaryXAxis: const CategoryAxis(),
  series: <LineSeries<SalesData, String>>[
    LineSeries<SalesData, String>(
      dataSource: [
        SalesData('一月', 35),
        SalesData('二月', 28),
        SalesData('三月', 34),
        SalesData('四月', 32),
        SalesData('五月', 40),
      ],
      xValueMapper: (data, _) => data.month,
      yValueMapper: (data, _) => data.sales,
      name: '销售额',
      markerSettings: const MarkerSettings(isVisible: true),
    )
  ],
)

class SalesData {
  final String month;
  final double sales;
  SalesData(this.month, this.sales);
}

// 环形图
SfCircularChart(
  legend: const Legend(isVisible: true),
  series: <CircularSeries>[
    DoughnutSeries<ChartData, String>(
      dataSource: chartData,
      xValueMapper: (data, _) => data.category,
      yValueMapper: (data, _) => data.value,
      dataLabelSettings: const DataLabelSettings(isVisible: true),
    )
  ],
)

✨ 动画库

flutter_animate(推荐)

最简单易用的动画库。

dependencies:
  flutter_animate: ^4.5.0
import 'package:flutter_animate/flutter_animate.dart';

// 基本动画
Text('Hello')
  .animate()
  .fadeIn(duration: 500.ms)
  .slideY(begin: 0.3, end: 0)
  
// 链式动画
Container()
  .animate()
  .fade(duration: 300.ms)
  .scale(delay: 300.ms)
  .move(delay: 600.ms, duration: 300.ms)
  
// 循环动画
Icon(Icons.favorite)
  .animate(onPlay: (controller) => controller.repeat())
  .scale(begin: const Offset(1, 1), end: const Offset(1.2, 1.2))
  .then()
  .scale(begin: const Offset(1.2, 1.2), end: const Offset(1, 1))

// 列表动画
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(title: Text(items[index]))
      .animate()
      .fadeIn(delay: (100 * index).ms)
      .slideX(begin: 0.5, end: 0);
  },
)

// 交互动画
ElevatedButton(
  onPressed: () {},
  child: const Text('按钮'),
)
  .animate(target: isHovered ? 1 : 0)
  .scale(begin: const Offset(1, 1), end: const Offset(1.1, 1.1))

lottie(JSON 动画)

播放 Lottie JSON 动画文件。

dependencies:
  lottie: ^3.1.0
import 'package:lottie/lottie.dart';

// 从 assets 加载
Lottie.asset(
  'assets/animations/loading.json',
  width: 200,
  height: 200,
  fit: BoxFit.contain,
)

// 从网络加载
Lottie.network(
  'https://assets.lottiefiles.com/packages/xxx.json',
  width: 200,
  height: 200,
)

// 控制动画
class LottieExample extends StatefulWidget {
  @override
  State<LottieExample> createState() => _LottieExampleState();
}

class _LottieExampleState extends State<LottieExample>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Lottie.asset(
          'assets/animations/heart.json',
          controller: _controller,
          onLoaded: (composition) {
            _controller.duration = composition.duration;
          },
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IconButton(
              icon: const Icon(Icons.play_arrow),
              onPressed: () => _controller.forward(),
            ),
            IconButton(
              icon: const Icon(Icons.pause),
              onPressed: () => _controller.stop(),
            ),
            IconButton(
              icon: const Icon(Icons.replay),
              onPressed: () => _controller.reset(),
            ),
          ],
        ),
      ],
    );
  }
}

获取 Lottie 动画资源:

  • LottieFiles - 最大的 Lottie 动画库
  • Icons8 - 动画图标

rive(高级交互动画)

支持复杂交互的动画引擎。

dependencies:
  rive: ^0.13.2
import 'package:rive/rive.dart';

// 基本使用
RiveAnimation.asset(
  'assets/animations/example.riv',
  fit: BoxFit.cover,
)

// 带状态机控制
class RiveExample extends StatefulWidget {
  @override
  State<RiveExample> createState() => _RiveExampleState();
}

class _RiveExampleState extends State<RiveExample> {
  SMITrigger? _trigger;

  void _onRiveInit(Artboard artboard) {
    final controller = StateMachineController.fromArtboard(artboard, 'State Machine 1');
    if (controller != null) {
      artboard.addController(controller);
      _trigger = controller.findInput<bool>('trigger') as SMITrigger?;
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => _trigger?.fire(),
      child: RiveAnimation.asset(
        'assets/animations/interactive.riv',
        onInit: _onRiveInit,
      ),
    );
  }
}

获取 Rive 动画:

  • Rive Community - Rive 社区资源

🎯 图标库

font_awesome_flutter

最流行的图标库 Font Awesome。

dependencies:
  font_awesome_flutter: ^10.7.0
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

// 实心图标
FaIcon(FontAwesomeIcons.solidHeart, color: Colors.red)

// 常规图标
FaIcon(FontAwesomeIcons.heart)

// 品牌图标
FaIcon(FontAwesomeIcons.github)
FaIcon(FontAwesomeIcons.twitter)
FaIcon(FontAwesomeIcons.weixin)

// 带大小
FaIcon(FontAwesomeIcons.star, size: 30)

line_icons

Line Icons 风格图标。

dependencies:
  line_icons: ^2.0.3
import 'package:line_icons/line_icons.dart';

Icon(LineIcons.home)
Icon(LineIcons.user)
Icon(LineIcons.cog)
Icon(LineIcons.heart)
Icon(LineIcons.search)

// 或使用常量类
Icon(LineIcons.values[LineIcons.home])

iconsax_flutter

现代简约风格图标。

dependencies:
  iconsax_flutter: ^1.0.0
import 'package:iconsax_flutter/iconsax_flutter.dart';

Icon(Iconsax.home)
Icon(Iconsax.user)
Icon(Iconsax.setting)
Icon(Iconsax.heart)
Icon(Iconsax.notification)

// 带样式
Icon(Iconsax.home_1)  // 变体
Icon(Iconsax.home_2)  // 另一个变体

自定义图标(iconfont)

使用阿里巴巴 iconfont 的自定义图标:

  1. 在 iconfont.cn 选择图标,下载字体文件
  2. 将 .ttf 文件放到 assets/fonts/ 目录
  3. 在 pubspec.yaml 中配置:
flutter:
  fonts:
    - family: MyIcons
      fonts:
        - asset: assets/fonts/iconfont.ttf
  1. 创建图标类:
class MyIcons {
  static const IconData home = IconData(0xe600, fontFamily: 'MyIcons');
  static const IconData user = IconData(0xe601, fontFamily: 'MyIcons');
  static const IconData settings = IconData(0xe602, fontFamily: 'MyIcons');
}

// 使用
Icon(MyIcons.home)

🎁 UI 资源推荐

设计资源

资源说明链接
Dribbble设计灵感dribbble.com
Behance设计作品behance.net
MobbinApp 设计参考mobbin.com
Figma Community免费设计模板figma.com/community

Flutter UI 模板

项目说明GitHub
FlutterExampleApps完整 App 示例github.com/iampawan/FlutterExampleApps
Best-Flutter-UI-Templates精美 UI 模板github.com/mitesh77/Best-Flutter-UI-Templates
flutter-ui-niceUI 设计示例github.com/nickmilo/flutter-ui-nice

颜色工具

工具说明链接
Coolors配色生成器coolors.co
Color Hunt配色方案colorhunt.co
Material Color ToolMaterial 配色material.io/resources/color

📝 小结

这一章我们介绍了丰富的 UI 资源:

分类推荐特点
内置组件Material 3官方支持,最稳定
UI 框架GetWidget组件最全面
图表fl_chart高度可定制
动画flutter_animate, lottie简单易用
图标font_awesome_flutter最流行

UI 开发建议

  1. 先熟练内置组件 - Material 组件已经很丰富
  2. 按需引入第三方库 - 不要盲目引入太多包
  3. 保持风格统一 - 不要混用多种 UI 框架
  4. 多看优秀设计 - 提升审美能力
  5. 善用设计工具 - 配色、图标等工具

💪 练习题

  1. 使用 Material 3 组件构建一个设置页面
  2. 使用 GetWidget 创建一个卡片列表
  3. 使用 fl_chart 实现一个简单的数据统计页面
  4. 使用 flutter_animate 为列表添加入场动画

🚀 下一步

掌握了 UI 框架和组件库后,你可以前往 第15章 - 状态管理进阶,学习更强大的状态管理方案!


由 编程指南 提供

最近更新: 2026/2/3 16:24
Contributors: 王长安
Next
附录B - 项目结构最佳实践