怎么做网站淘宝转换工具,phpcms获取网站名称,服装网站的建设,帮传销做网站违法吗学习 Flutter (一)
1. 引言 什么是 Flutter#xff1f; Flutter 是 Google 开发的一套开源 UI 框架#xff0c;主要用于构建高性能、高保真、跨平台的应用程序。使用一套 Dart 编写的代码#xff0c;开发者可以同时构建适用于#xff1a; Android iOS Web Windows、mac…学习 Flutter (一)
1. 引言 什么是 Flutter Flutter 是 Google 开发的一套开源 UI 框架主要用于构建高性能、高保真、跨平台的应用程序。使用一套 Dart 编写的代码开发者可以同时构建适用于 Android iOS Web Windows、macOS、Linux 桌面端 嵌入式平台如车载、IoT 设备 Flutter 的核心特性包括 热重载Hot Reload可以快速预览修改结果提高开发效率。 自绘式渲染引擎Skia绕过原生控件确保 UI 在各平台一致。 丰富的组件库Widgets一切皆组件易于构建复杂界面。 灵活的布局系统支持响应式和复杂嵌套的布局设计。 为什么选择 Flutter 选择 Flutter 的理由主要包括以下几点 跨平台统一开发 用一套 Dart 代码即可构建多端应用极大节省开发和维护成本。 高性能 Flutter 拥有自己的渲染引擎不依赖原生控件性能接近原生尤其适合需要高帧率渲染的场景。 快速开发体验 热重载和热重启机制加快了开发调试的迭代周期提升开发效率。 丰富的生态 Flutter 拥有大量开源插件如 camera、http、firebase 等支持多数主流功能的快速集成。 社区支持良好 Google 官方持续更新社区活跃度高文档齐全资源丰富。 本文档的目标和读者定位 文档目标 本系列文档旨在从零开始系统性讲解 Flutter 框架的核心概念与开发实战内容。通过理论与实操结合帮助读者完成从入门到进阶的技能成长路径。 具体目标包括 理解 Flutter 的核心组件与布局体系 能够独立开发一个简单完整的 Flutter 应用 掌握跨平台适配、状态管理等实用技能
2. 环境准备
2.1 安装 Android Studio 下载地址与版本选择 官网地址最好开VPN访问 developer.android.com/studio 或者 Android Studio 下载文件归档 | Android Developers Android Studio 简单介绍 Android Studio 是 Google 官方推出的 Android 应用开发集成环境IDE基于 JetBrains 的 IntelliJ IDEA 平台构建。它是开发 Android 原生应用和 Flutter 应用的推荐工具提供了丰富的功能来帮助开发者高效编写、调试和测试应用程序, Android Studio 是一个功能齐全、插件丰富的现代化开发环境不仅适用于传统 Android 开发也是目前 Flutter 开发的首选 IDE。无论是新手学习还是企业级项目开发Android Studio 都提供了良好的开发支持与工具生态
2.2 安装 Flutter SDK Flutter SDK 下载与安装步骤Windows 官方地址Archive | Flutter 设置环境变量 在系统环境变量中新建变量 变量名PUB_HOSTED_URL
变量值https://pub.flutter-io.cn变量名FLUTTER_STORAGE_BASE_URL
变量值https://storage.flutter-io.cn在系统变量 PATH 中添加 Flutter bin目录 D:\flutter_windows_3.24.1-stable\flutter\binAndroid Studio 下载 SDK 工具和 Android SDK Comman-line Tools 并下载 Flutter 和 Dart 插件 执行命令 flutter doctor -v首次执行 Flutter 命令会从网络中拉取 Dart SDK、flutter工具等这个过程会比较漫长 可能一直卡在 C:\Users\zengjh1D:\flutter_windows_3.22.1-stable\flutter\bin\flutter.bat doctor Checking Dart SDK version… Downloading Dart SDK from Flutter engine … 只能耐心等待或者关闭重来下载完后会显示 flutter 结果 [√] Flutter (Channel stable, 3.24.1, on Microsoft Windows [版本 10.0.19044.5737], locale zh-CN)• Flutter version 3.24.1 on channel stable at D:\flutter_windows_3.24.1-stable\flutter• Upstream repository https://github.com/flutter/flutter.git• Framework revision 5874a72aa4 (11 months ago), 2024-08-20 16:46:00 -0500• Engine revision c9b9d5780d• Dart version 3.5.1• DevTools version 2.37.2• Pub download mirror https://pub.flutter-io.cn• Flutter download mirror https://storage.flutter-io.cn[√] Windows Version (Installed version of Windows is version 10 or higher)[!] Android toolchain - develop for Android devices (Android SDK version 35.0.0)• Android SDK at D:\SDK• Platform android-35, build-tools 35.0.0• ANDROID_SDK_ROOT D:\SDK• Java binary at: C:\Program Files\Java\jdk-17\bin\java• Java version Java(TM) SE Runtime Environment (build 1735-LTS-2724)X Android license status unknown.Run flutter doctor --android-licenses to accept the SDK licenses.See https://flutter.dev/to/windows-android-setup for more details.[√] Chrome - develop for the web• Chrome at C:\Users\zengjh1\AppData\Local\Google\Chrome\Application\chrome.exe[X] Visual Studio - develop Windows appsX Visual Studio not installed; this is necessary to develop Windows apps.Download at https://visualstudio.microsoft.com/downloads/.Please install the Desktop development with C workload, including all of its default components[√] Android Studio (version 2024.3)• Android Studio at F:\Program Files\Android\Android Studio• Flutter plugin can be installed from:https://plugins.jetbrains.com/plugin/9212-flutter• Dart plugin can be installed from:https://plugins.jetbrains.com/plugin/6351-dart• Java version OpenJDK Runtime Environment (build 21.0.6-13355223-b631.42)[√] Connected device (3 available)• Windows (desktop) • windows • windows-x64 • Microsoft Windows [版本 10.0.19044.5737]• Chrome (web) • chrome • web-javascript • Google Chrome 117.0.5938.63• Edge (web) • edge • web-javascript • Microsoft Edge 138.0.3351.65[√] Network resources• All expected network resources are available.! Doctor found issues in 2 categories.会提示我们那些工具缺少了什么我们用的是 AndroidStudio所以只要保证 AndroidStudio 这一栏没问题就行
2.3 安装 Dart 插件和 Flutter 插件 在 Android Studio 中安装插件的方法 在 File - Setting - Plugins - Marketplace 下搜索 Dart 和 Flutter 插件下载安装即可。
2.4 连接真实设备
设备开启开发者 USB 调试模式设备连接与调试授权
3. 创建第一个 Flutter 项目
3.1 通过 Android Studio 创建 Flutter 项目 选择 Flutter 项目 配置 Flutter SDK path 项目配置
3.2 项目结构介绍 lib/ 文件夹及主要 Dart 文件 lib/ 是 Dart 代码的主目录 main.dart 是应用的启动文件负责引导整个 UI 构建。 项目结构建议按模块划分如 pages/ 、widgets/ 等便于组织和维护。 pubspec.yaml 文件含义 pubspec.yaml 是 Flutter 和 Dart 项目的配置文件用于声明项目的依赖、资源、版本信息、打包配置等内容。 它类似于其他语言生态的配置文件例如 Node.js 的 package.json Java 的 pom.xml Python 的 requirements.txt 项目功能描述name, version定义项目元信息dependencies项目运行所需依赖dev_dependencies测试/开发所需依赖flutter/assets声明项目使用的图片、JSON、音频等资源flutter/fonts配置自定义字体uses-material-design是否使用 Material 风格设计
4. 编写第一个 Flutter 界面
4.1 了解 Widget 体系 StatelessWidget 和 StatefulWidget 区别 StatelessWidget无状态组件 StatelessWidget 是 不可变的 其构建内容在生命周期中不会发生变化。 适用场景 内容不需要更新比如固定文本、图标、样式按钮等。 UI 仅依赖构造时传入的数据。 class HelloText extends StatelessWidget {final String name;const HelloText({super.key, required this.name});overrideWidget build(BuildContext context) {return Text(Hello, $name);}
}StatefulWidget有状态组件 StatefulWidget 是 可变的 拥有自己的状态对象 State 当状态改变时会触发 UI 重新构建 (setState())。 适用场景 UI 需要根据用户交互或数据更新而改变 比如按钮点击计数、输入框内容、动画等。 class CounterWidget extends StatefulWidget {const CounterWidget({super.key});overrideStateCounterWidget createState() _CounterWidgetState();
}class _CounterWidgetState extends StateCounterWidget {int _count 0;void _increment() {setState(() {_count;});}overrideWidget build(BuildContext context) {return Column(children: [Text(Count: $_count),ElevatedButton(onPressed: _increment, child: const Text(Increment)),],);}
}区别总结 特性StatelessWidgetStatefulWidget状态是否可变否不可变是可变是否持有状态对象否是通过 State 类UI 是否可动态更新否是调用 setState()重建方式构造函数参数变化时重建setState() 调用后重建常见应用场景静态文本、图标、按钮等表单输入、计数器、动画等 Widget 树的概念 在 Flutter 中一切都是 Widget页面 UI 是由各种 Widget 通过嵌套组合而成的这种嵌套结构被称为 Widget 树 什么是 Widget 树 Widget 树是指一个页面上的所有元素按钮、文字、图片、容器等以”树“的结构从上到下排列组合而成。 每一个 Widget 都可能包含子 Widget它们像”树枝”一样组成整个页面的布局和逻辑 MaterialApp
└── Scaffold├── AppBar└── Body└── Column├── Text└── ElevatedButtonWidget 树的层级关系 父 Widget包含其他 Widget容器、布局等 子 Widget被包含在某个父 Widget 中 Flutter 会从上往下递归构建、渲染、更新整课 Widget 树 为什么理解 Widget 树很重要 调试和布局排查Widget 树帮助你理解某个组件在页面中的层级与位置 性能优化可以判断哪些 Widget 频繁重建是否可以抽离为 Stateless 构建思想转变传统 UI 框架强调“修改视图”Flutter 强调“重建 Widget 树”。 Widget 树的可视化工具 Flutter 提供了调试工具 Flutter Inspector在 Android Studio、VSCode 中可用 可以查看实际 Widget 树结构帮助开发者理解页面构造 总结 概念说明StatelessWidget不可变组件适合静态展示构建后不会改变StatefulWidget可变组件内部状态变化时可使用 setState() 触发重建Widget 树所有 Widget 按嵌套结构组成的一棵树构成 UI 的骨架
4.2 修改默认代码为“Hello World” 替换原先 main.dart 内容为 import package:flutter/material.dart;void main() runApp(const MyApp());class MyApp extends StatelessWidget {const MyApp();overrideWidget build(BuildContext context) {return const MaterialApp(home: HelloWorldPage(),);}
}class HelloWorldPage extends StatelessWidget {const HelloWorldPage();overrideWidget build(BuildContext context) {return const Scaffold(body: Center(child: Text(Hello World,style: TextStyle(fontSize: 24),),),);}
}5. Flutter 组件详解
5.1 基础组件 Text文本显示 用于在界面中显示一段文本 Text(Hello Flutter)常用属性 属性名类型说明styleTextStyle设置字体大小、颜色、粗细、行高等textAlignTextAlign文本对齐方式如 center、leftmaxLinesint显示的最大行数overflowTextOverflow文本超出时的处理如 ellipsis示例 Text(欢迎学习 Flutter!,style: TextStyle(fontSize: 20,color: Colors.blue,fontWeight: FontWeight.bold),textAlign: TextAlign.center,maxLines: 1,overflow: TextOverflow.ellipsis,)Image图片 用于显示本地或网络图片 常用构造函数 函数名说明Image.asset()加载项目中的本地图片Image.network()加载网络图片Image.file()加载本地文件系统中的图片Image.memory()加载内存中的图片示例 import package:flutter/material.dart;void main() runApp(MyApp());class MyApp extends StatelessWidget {MyApp();overrideWidget build(BuildContext context) {return MaterialApp(home: HelloWorldPage(),);}
}class HelloWorldPage extends StatelessWidget {HelloWorldPage();overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Image.network(https://img.shetu66.com/zt/1661475606815_a10229ff.jpg,width: 200,height: 80,),),);}
}Icon图标 用于显示 Material Design 风格的图标 基本用法 Icon(Icons.home)常用属性 属性名说明Icons.xxx图标名Flutter 内置许多图标size图标大小color图标颜色示例 import package:flutter/material.dart;void main() runApp(MyApp());class MyApp extends StatelessWidget {MyApp();overrideWidget build(BuildContext context) {return MaterialApp(home: HelloWorldPage(),);}
}class HelloWorldPage extends StatelessWidget {HelloWorldPage();overrideWidget build(BuildContext context) {return Scaffold(body: Center(child: Icon(Icons.favorite,color: Colors.red,size: 32,),),);}
}对比
组件用途典型构造方法常用属性Text显示文字Text(xxx)style, textAlignImage显示图片Image.asset(), Image.network()width, height, fitIcon显示图标Icon(Icons.xxx)size, color
5.2 布局组件 Container容器 Container 是一个组合型的组件组合了尺寸、边距、填充、对齐、颜色、装饰、变换等功能。 它本身不渲染任何内容但可以承载一个子 Widget并通过属性来控制它的展示方式它相当于 HTML 中的 div CSS 中的 margin/padding/background/transform 组合体。 常用属性 属性类型说明childWidget子组件width / heightdouble设置容器的宽度和高度marginEdgeInsets外边距paddingEdgeInsets内边距对子组件生效colorColor背景颜色不能与 decoration.color 同时使用alignmentAlignment控制子组件在容器内的位置decorationBoxDecoration背景装饰如圆角、边框、背景图等transformMatrix4容器的几何变换如旋转、缩放、平移示例 设置宽高 背景色 子组件居中 import package:flutter/material.dart;void main() runApp(MyApp());class MyApp extends StatelessWidget {MyApp();overrideWidget build(BuildContext context) {return MaterialApp(home: HelloWorldPage(),);}
}class HelloWorldPage extends StatelessWidget {HelloWorldPage();overrideWidget build(BuildContext context) {return Container(width: 200,height: 100,color: Colors.blue,alignment: Alignment.center,child:const Text(Hello Container, style: TextStyle(color: Colors.white)),);}
}设置内边距和外边距 import package:flutter/material.dart;void main() runApp(MyApp());class MyApp extends StatelessWidget {MyApp();overrideWidget build(BuildContext context) {return MaterialApp(home: HelloWorldPage(),);}
}class HelloWorldPage extends StatelessWidget {HelloWorldPage();overrideWidget build(BuildContext context) {return Container(margin: const EdgeInsets.all(16),padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),color: Colors.green,child: const Text(带边距的文本),);}
}使用装饰 decoration import package:flutter/material.dart;void main() runApp(MyApp());class MyApp extends StatelessWidget {MyApp();overrideWidget build(BuildContext context) {return MaterialApp(home: HelloWorldPage(),);}
}class HelloWorldPage extends StatelessWidget {HelloWorldPage();overrideWidget build(BuildContext context) {return Container(width: 150,height: 150,decoration: BoxDecoration(color: Colors.orange,borderRadius: BorderRadius.circular(16),border: Border.all(color: Colors.black, width: 2),),child: const Center(child: Text(装饰效果)),);}
}添加变换旋转 import package:flutter/material.dart;void main() runApp(MyApp());class MyApp extends StatelessWidget {MyApp();overrideWidget build(BuildContext context) {return MaterialApp(home: HelloWorldPage(),);}
}class HelloWorldPage extends StatelessWidget {HelloWorldPage();overrideWidget build(BuildContext context) {return Container(width: 100,height: 100,color: Colors.purple,transform: Matrix4.rotationZ(0.2),alignment: Alignment.center,child: const Text(旋转),);}
}Padding内边距 Padding 是 Flutter 中用于给子组件添加 内边距padding 的布局组件。 它的作用是在子组件的外部但在边框内部增加空白区域。 语法结构 Padding(padding: EdgeInsets.all(8.0), // 设置内边距child: Text(Hello Padding),
)示例 四边统一内边距 Padding(padding: EdgeInsets.all(16),child: Text(我有 16 的内边距),
)水平、垂直内边距不同 Padding(padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),child: Text(左右 24上下 12),
)仅指定某个方向 Padding(padding: EdgeInsets.only(top: 20, left: 10),child: Text(仅上边距 20左边距 10),
)Padding 与 Container 的区别 特性PaddingContainer设置内边距专门用于设置内边距但只是组合属性的一部分设置颜色、大小不支持可以设置宽高、颜色、装饰等推荐场景专注间距控制通用容器做样式和布局控制更全面 Align对齐 Align 是 Flutter 中用于 对子组件进行位置控制 的组件。它会在自身范围内将 child 放置到指定的位置例如居中、左上、右下等 基本语法 Align(alignment: Alignment.center, // 默认值child: Text(居中显示)
)alignment 属性详解 常量对应位置Alignment.topLeft左上角Alignment.topCenter上中Alignment.topRight右上角Alignment.centerLeft左中Alignment.center中间默认Alignment.centerRight右中Alignment.bottomLeft左下角Alignment.bottomCenter下中Alignment.bottomRight右下角本质上alignment 是一个二维坐标系 ”(-1, -1) 表示左上角(1,1) 表示右下角(0, 0) 表示正中间。“ 示例 文字显示在右下角 Align(alignment: Alignment.bottomRight,child: Text(右下角文字),
)放一张图片到左上角 Align(alignment: Alignment.topLeft,child: Image.asset(assets/images/avatar.png, width: 60),
)附加属性 widthFactor 和 heightFactor 这些属性可以影响 Align 本身的大小 widthFactor 子组件宽度 × 倍数作为 Align 的宽度 heightFactor 子组件高度 × 倍数作为 Align 的高度 Align(alignment: Alignment.center,widthFactor: 2,heightFactor: 2,child: Text(我是 2 倍大),)和其他对齐组件的区别 组件功能描述Align精确控制子组件在父组件中的位置Center相当于 Align(alignment: Alignment.center)Padding设置内边距但不能控制子组件的具体位置Positioned用于 Stack 中绝对定位 Center居中 Center 是一个非常简单的布局组件它的作用是将子组件放在父容器的中心位置 基本语法 Center(child: Text(居中显示),
)它会自动让 Text 或其他子组件在父容器中 水平居中 垂直居中 示例 居中显示文本 Center(child: Text(Hello Center,style: TextStyle(fontSize: 24),),
)居中显示图片 Center(child: Image.asset(assets/images/logo.png, width: 100),
)结合 Container 使用 Container(width: 300,height: 300,color: Colors.blue.shade100,child: Center(child: Text(我是居中的文字),),
)Center 和其他布局组件的区别 组件用途特点Center子组件居中最简单等价于 Align.centerAlign子组件任意对齐更灵活需要手动指定 alignmentPadding增加空白区域但不控制对齐方式PositionedStack 中做绝对定位需要配合 Stack 使用 Row水平排列 Row 是一个横向布局组件用于 将多个组件水平排列在一行内 基本语法 Row(children: [Text(A),Text(B),Text(C),],
)这段代码会将 A B C 横向排在一行里。 常用属性详情 属性名类型说明childrenListWidget子组件列表mainAxisAlignmentMainAxisAlignment主轴水平方向对齐方式crossAxisAlignmentCrossAxisAlignment交叉轴垂直方向对齐方式mainAxisSizeMainAxisSize主轴尺寸最大/最小是否占满可用空间textDirectionTextDirection布局方向从左到右默认还是从右到左 mainAxisAlignment 对齐选项水平 属性效果MainAxisAlignment.start左对齐默认MainAxisAlignment.center水平居中MainAxisAlignment.end右对齐MainAxisAlignment.spaceBetween两端对齐子项平均分布MainAxisAlignment.spaceAround子项周围空白相等MainAxisAlignment.spaceEvenly子项之间空白完全相等示例 Row(mainAxisAlignment: MainAxisAlignment.center,children: const [Icon(Icons.star, color: Colors.red),Icon(Icons.star_border, color: Colors.red),Icon(Icons.star_half, color: Colors.red),],)crossAxisAlignment 对齐选项垂直 属性效果CrossAxisAlignment.start顶部对齐CrossAxisAlignment.center垂直居中默认CrossAxisAlignment.end底部对齐CrossAxisAlignment.stretch拉伸子项填满垂直空间baseline需设置 textBaseline按文本基线对齐 Column垂直排列 Column 是一个 竖直方向布局组件 可以让多个子组件 从上到下一次排列 基本语法 Column(children: [Text(第一行),Text(第二行),Text(第三行),],
)常用属性解释 属性名类型说明childrenListWidget子组件列表mainAxisAlignmentMainAxisAlignment主轴竖直方向对齐方式crossAxisAlignmentCrossAxisAlignment交叉轴水平方向对齐方式mainAxisSizeMainAxisSize主轴大小控制是否占满可用垂直空间 主轴对齐mainAxisAlignment 控制子组件在竖直方向上的排列方式 属性值效果MainAxisAlignment.start从顶部开始默认MainAxisAlignment.center垂直居中MainAxisAlignment.end底部对齐MainAxisAlignment.spaceBetween上下贴边中间平均分布MainAxisAlignment.spaceAround每个子组件周围间距相等MainAxisAlignment.spaceEvenly所有子组件间距完全相等 交叉轴对齐crossAxisAlignment 控制子组件在水平方向上的对齐方式 属性值效果CrossAxisAlignment.start左对齐默认CrossAxisAlignment.center水平居中CrossAxisAlignment.end右对齐CrossAxisAlignment.stretch拉伸子组件到最大宽度 示例 简单垂直排布 Column(mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: const [Text(标题),SizedBox(height: 10),Text(副标题),SizedBox(height: 10),Icon(Icons.star, size: 32),],)加背景 居中演示配合 Container Container(width: double.infinity,height: 300,color: Colors.blue.shade50,child: Column(mainAxisAlignment: MainAxisAlignment.spaceEvenly,crossAxisAlignment: CrossAxisAlignment.center,children: const [Text(上),Text(中),Text(下),],),)Stack层叠布局 Stack 是一个 堆叠布局组件 允许多个子组件 按照 z 轴 前后方向叠加在一起 基本语法 Stack(children: [Container(width: 200, height: 200, color: Colors.blue),Positioned(top: 20,left: 20,child: Icon(Icons.star, size: 50, color: Colors.white),),],
)常用属性解释 属性名类型说明childrenListWidget所有子组件越靠后越在上层alignmentAlignment控制非 Positioned 子组件的位置fitStackFit控制子组件尺寸如何适应 StackclipBehaviorClip是否裁剪超出部分默认 Clip.hardEdge Stack vs Positioned Stack 用来定义多个叠加的层 Positioned 用来对某个子组件进行绝定位 和基本语法示例对比 Stack(children: [Container(color: Colors.yellow, width: 200, height: 200),Positioned(bottom: 10,right: 10,child: Text(右下角),),],
)alignment对非 Positioned 的子组件对齐 Stack(alignment: Alignment.center,children: [Container(width: 100, height: 100, color: Colors.red),Text(居中), // 自动居中],)5.3 按钮和交互组neiElevatedButton / TextButton / OutlinedButton各种按钮 ElevatedButton / TextButton / OutlinedButton各种按钮 按钮类型外观描述适用场景ElevatedButton有阴影、背景填充、立体感强用于强调操作如“提交”TextButton无边框、无背景仅文本用于辅助操作、二级选项OutlinedButton有边框但无背景用于不那么主要的操作按钮 ElevatedButton 立体按钮 Container(child: Column(children: [ElevatedButton(onPressed: () {print(点击了 ElevatedButton);},child: Text(确定),)],),color: Colors.white,)常用于强调主要操作例如 “登录”、“提交”。 TextButton纯文本按钮 TextButton(onPressed: () {print(点击了 TextButton);},child: Text(取消),)用于不那么显眼的按钮比如“忘记密码”、“查看更多”。 OutlinedButton带边框按钮 OutlinedButton(onPressed: () {print(点击了 OutlinedButton);},child: Text(边框按钮),
)用于中性操作比如“跳过”、“稍后再说”。 自定义按钮样式 三种按钮都支持使用 style 参数来自定义外观使用 ButtonStyle 类 ElevatedButton(onPressed: () {},style: ElevatedButton.styleFrom(primary: Colors.blue, // 背景色onPrimary: Colors.white, // 文字颜色padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12),),),child: Text(自定义样式),
)使用场景建议 场景推荐按钮类型提交、主操作ElevatedButton取消、跳过、轻操作TextButton次要但需强调边界操作OutlinedButton图标 文本按钮*.icon() 系列 GestureDetector手势识别 GestureDetector 是一个 手势识别器 可以监听用户在屏幕上的各种操作手势如 点击Tap 双机Double Tap 长按Long Press 拖动Drag 缩放Scale 基本语法 GestureDetector(onTap: () {print(点击了组件);},child: Container(color: Colors.blue,padding: EdgeInsets.all(20),child: Text(点我),),
)常用事件一览 属性名类型说明onTapvoid Function()单击onDoubleTapvoid Function()双击onLongPressvoid Function()长按onPanUpdateFunction(DragUpdateDetails)拖动时触发全向onPanStart / onPanEnd-拖动开始 / 结束onScaleUpdateFunction(ScaleUpdateDetails)双指缩放 示例 点击、长按、双击事件 GestureDetector(onTap: () print(点击),onDoubleTap: () print(双击),onLongPress: () print(长按),child: Container(padding: EdgeInsets.all(20),color: Colors.lightGreen,child: Text(点我试试),),
)拖动onPanUpdate) GestureDetector(onPanUpdate: (details) {print(dx: ${details.delta.dx}, dy: ${details.delta.dy});},child: Container(width: 200,height: 200,color: Colors.orange,child: Center(child: Text(拖动我)),),
)缩放onScaleUpdate GestureDetector(onScaleUpdate: (details) {print(缩放比例${details.scale});},child: Image.asset(assets/images/logo.png),
)总结
功能是否支持示例属性点击支持onTap双击支持onDoubleTap长按支持onLongPress拖动支持onPanUpdate缩放支持onScaleUpdate支持嵌套其他组件支持child无视觉效果非按钮支持需要自定义样式InkWell水波纹效果点击 InkWell 是一个 带水波纹涟漪点击效果的手势识别组件。 相比 GestureDetector 它有更好的 Material 设计风格的视觉效果 它属于 Material 组件体系的一部分使用时需要有 Material 组件作为“水波纹的绘制容器” 基本用法 InkWell(onTap: () {print(点击了 InkWell);},child: Padding(padding: EdgeInsets.all(16),child: Text(点我),),
)点击时会看到水波纹从点击点扩散开来 常用属性 属性名类型说明onTapvoid Function()?点击事件onDoubleTapvoid Function()?双击事件onLongPressvoid Function()?长按事件borderRadiusBorderRadius设置水波纹圆角splashColorColor设置水波纹颜色highlightColorColor按下时的背景色childWidget显示内容 配合 Material 使用 必须 Material(color: Colors.blue[50],borderRadius: BorderRadius.circular(12),child: InkWell(onTap: () {print(点到了卡片);},borderRadius: BorderRadius.circular(12),splashColor: Colors.redAccent.withOpacity(0.2),child: Padding(padding: EdgeInsets.all(20),child: Text(有点击水波纹的卡片),),),)和 GestureDetectro 区别对比 对比点GestureDetectorInkWell是否有视觉反馈无水波纹有水波纹是否依赖 Material不依赖必须依赖 Material 父组件支持的手势种类拖动、缩放、滑动等更丰富主要用于点击相关使用场景自定义复杂交互通常用于按钮、卡片、列表点击反馈等
5.4 输入框和表单 TextField文本输入 TextField 是最常用的文本输入组件用于实现表单的输入、搜索框、聊天框等各种输入功能 基本用法 TextField(decoration: InputDecoration(labelText: 用户名,hintText: 请输入用户名,border: OutlineInputBorder(),),
)效果一个带标签、提示文字、边框的输入框 常用属性详情 属性名类型说明controllerTextEditingController控制和监听输入框内容decorationInputDecoration装饰输入框如提示、图标、边框等obscureTextbool是否隐藏输入内容用于密码keyboardTypeTextInputType输入类型文本、数字、邮箱等maxLinesint输入框最大行数onChangedFunction(String)文本改变时回调onSubmittedFunction(String)用户按下“完成/提交”时的回调enabledbool是否可编辑readOnlybool是否只读 示例 带控制器示例获取输入内容
class TextFieldExample extends StatelessWidget {final TextEditingController _controller TextEditingController();overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(TextField 示例)),body: Padding(padding: const EdgeInsets.all(16.0),child: Column(children: [TextField(controller: _controller,decoration: InputDecoration(labelText: 输入内容),),SizedBox(height: 20),ElevatedButton(onPressed: () {print(你输入了: ${_controller.text});},child: Text(提交))],),),);}
}密码框隐藏输入 TextField(obscureText: true,decoration: InputDecoration(labelText: 密码,border: OutlineInputBorder(),),)不同输入类型 输入类型示例设置文本默认keyboardType: TextInputType.text数字keyboardType: TextInputType.number电话keyboardType: TextInputType.phone邮箱keyboardType: TextInputType.emailAddress 多行输入 TextField(maxLines: 5,decoration: InputDecoration(labelText: 多行备注),
) 自定义装饰 InputDecoration 示例 TextField(decoration: InputDecoration(prefixIcon: Icon(Icons.person),suffixIcon: Icon(Icons.clear),labelText: 用户名,hintText: 请输入用户名,border: OutlineInputBorder(),),
) Checkbox多选框 Checkbox 是一个可以勾选/取消的组件只有两个状态true / false ) 可以搭配文字或图标一起使用。 基本用法 bool _isChecked false;Checkbox(value: _isChecked,onChanged: (bool? value) {setState(() {_isChecked value!;});},
) 必须在 StatefulWidget 中使用因为复选框的值需要动态更新。 示例 class CheckBoxDemo extends StatefulWidget {override_CheckBoxDemoState createState() _CheckBoxDemoState();
}class _CheckBoxDemoState extends StateCheckBoxDemo {bool _isSelected false;overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Checkbox 示例)),body: Center(child: Row(mainAxisSize: MainAxisSize.min,children: [Checkbox(value: _isSelected,onChanged: (bool? value) {setState(() {_isSelected value!;});},),Text(_isSelected ? 已选中 : 未选中),],),),);}
} 常用属性 属性名类型说明valuebool当前是否勾选onChanged(bool?) → void勾选状态变化时的回调函数activeColorColor选中时的颜色checkColorColor号颜色tristatebool是否支持三种状态true/false/null搭配 CheckboxListTitle 复选框 标题 子标题 CheckboxListTile(title: Text(我同意协议),subtitle: Text(点击确认后继续),value: _isChecked,onChanged: (value) {setState(() {_isChecked value!;});},secondary: Icon(Icons.policy),controlAffinity: ListTileControlAffinity.leading,)总结 你想实现的功能使用方式或属性基本复选框Checkbox复选框 文字Row Text 或 CheckboxListTile支持不确定null状态tristate: true更好看的样式和布局用 CheckboxListTile Radio单选框 RadioT 是 Flutter 提供的泛型组件用于在多个选项中选择一个必须搭配 groupValue 一起使用。 最基本的用法示例 Radioint(value: 1,groupValue: _selectedValue,onChanged: (int? value) {setState(() {_selectedValue value!;});},
) value表示当前这个单选按钮的值 groupValue表示当前“选中的值” onChanged当点击时调用传入的就是 value 选择性别示例 class RadioDemo extends StatefulWidget {override_RadioDemoState createState() _RadioDemoState();
}class _RadioDemoState extends StateRadioDemo {String _gender 男;overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Radio 示例)),body: Column(children: [ListTile(title: Text(男),leading: RadioString(value: 男,groupValue: _gender,onChanged: (value) {setState(() {_gender value!;});},),),ListTile(title: Text(女),leading: RadioString(value: 女,groupValue: _gender,onChanged: (value) {setState(() {_gender value!;});},),),SizedBox(height: 20),Text(你选择的是$_gender),],),);}
}常用属性一览 属性名类型说明valueT当前这个选项的值groupValueT当前组中被选中的值onChangedFunction(T?)点击时回调activeColorColor选中状态颜色toggleablebool是否支持再次点击取消Flutter 3.7 Switch开关 Switch 是 Flutter 提供的滑动切换组件只有两个状态true 开启和 false 关闭 最基本的用法 bool _isOn false;Switch(value: _isOn,onChanged: (bool value) {setState(() {_isOn value;});},
) 必须在 StatefulWidget 中使用因为开关状态需要实时更新。 示例 控制某功能开关 class SwitchDemo extends StatefulWidget {override_SwitchDemoState createState() _SwitchDemoState();
}class _SwitchDemoState extends StateSwitchDemo {bool _isDarkMode false;overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Switch 示例)),body: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Switch(value: _isDarkMode,onChanged: (bool value) {setState(() {_isDarkMode value;});},),Text(_isDarkMode ? 暗黑模式已开启 : 暗黑模式已关闭),],),);}
} 常用属性 属性名类型说明valuebool当前开关状态onChanged(bool) → void状态变化回调函数activeColorColor开启时的主色圆点颜色activeTrackColorColor开启时轨道颜色inactiveThumbColorColor关闭时圆点颜色inactiveTrackColorColor关闭时轨道颜色materialTapTargetSizeMaterialTapTargetSize调整点击区域大小 Form 与 FormField表单管理 在 Flutter 中Form 和 FormField 是用于统一管理多个输入组件的表单系统可以方便地进行表单验证、提交等操作常用于登录、注册、反馈等界面。 什么是 Form 和 FormField 组件作用说明Form表单容器用于管理一组输入项字段FormField表单字段的基类如 TextFormFieldTextFormField 是最常用的 FormField 实现是带表单验证功能的输入框 Form 的基本结构 final _formKey GlobalKeyFormState();Form(key: _formKey,child: Column(children: [TextFormField(decoration: InputDecoration(labelText: 用户名),validator: (value) {if (value null || value.isEmpty) {return 请输入用户名;}return null;},),ElevatedButton(onPressed: () {if (_formKey.currentState!.validate()) {// 所有字段验证通过print(验证成功提交数据);}},child: Text(提交),),],),
) 关键知识点说明 项目说明FormState表单状态对象管理字段验证、保存等操作GlobalKeyFormState唯一标识表单获取 FormState 对象validate()执行所有字段的 validator 方法返回是否通过验证save()触发每个字段的 onSaved 回调如果设置reset()重置所有字段内容和状态 完整示例 class FormExample extends StatefulWidget {override_FormExampleState createState() _FormExampleState();
}class _FormExampleState extends StateFormExample {final _formKey GlobalKeyFormState();String _username ;String _password ;overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Form 表单示例)),body: Padding(padding: EdgeInsets.all(16),child: Form(key: _formKey,child: Column(children: [TextFormField(decoration: InputDecoration(labelText: 用户名),validator: (value) {if (value null || value.isEmpty) {return 请输入用户名;}return null;},onSaved: (value) {_username value!;},),TextFormField(decoration: InputDecoration(labelText: 密码),obscureText: true,validator: (value) {if (value null || value.length 6) {return 密码不能少于6位;}return null;},onSaved: (value) {_password value!;},),SizedBox(height: 20),ElevatedButton(onPressed: () {if (_formKey.currentState!.validate()) {_formKey.currentState!.save();print(用户名: $_username);print(密码: $_password);}},child: Text(提交),),],),),),);}
} TextField VS TextFormField 区别项TextFieldTextFormField表单验证支持无验证方法支持 validator/onSaved 等与 Form 配合使用需要单独管理状态可统一使用 Form 管理推荐使用场景简单输入框表单场景如登录、注册等 一些常用方法FormState 方法名说明validate()所有字段验证返回布尔值save()调用每个字段的 onSaved()reset()重置整个表单
5.5 滚动视图 ListView列表 ListView 是一个 可滚动的线性列表视图组件 可以直接或水平显示一系列子组件 最基本的用法 ListView(children: [ListTile(title: Text(第1项)),ListTile(title: Text(第2项)),ListTile(title: Text(第3项)),],
) 默认是垂直方向的超出屏幕会自动滚动。 常见构造方式 ListView children: 静态少量内容 ListView.builder: 动态列表推荐 ListView.separated: 带分隔线 ListView.custom: 高级自定义构造极少用 常用属性 属性名类型说明itemCountint列表项数量用于 builderitemBuilderIndexedWidgetBuilder构建每项内容的方法scrollDirectionAxis滚动方向Axis.vertical / horizontalreversebool是否反转列表显示顺序shrinkWrapbool是否根据内容自动收缩高度physicsScrollPhysics滚动行为如禁止、弹性等paddingEdgeInsets设置内边距 示例 class ListViewDemo extends StatelessWidget {final ListString items List.generate(20, (index) 项目 $index);overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(ListView 示例)),body: ListView.builder(itemCount: items.length,itemBuilder: (context, index) {return ListTile(leading: Icon(Icons.start),title: Text(items[index]),onTap: () {print(你点击了: ${items[index]});},);}));}
} GridView网格 GridView网格布局它是用来显示多列多行多列的组件常用于图片展示、商品列表、图标宫格菜单等场景。GridView 是一个支持滚动的二维网格布局组件和 ListView 类似但可以在横向上自动分布多个元素。 常用构造方法 GridView.count常规固定列数网格 GridView.count(crossAxisCount: 3,children: List.generate(9, index {return Container(alignment: Alignment.center,color: Colors.blue[100 * ((index % 8) 1)],child: Text(项 $index));});
);GridView.builder推荐用于大数据列表 GridView.builder(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, // 每行 2 个crossAxisSpacing: 10, // 横向间距mainAxisSpacing: 10, // 纵向间距childAspectRatio: 1.5, // 宽高比默认是 1),itemCount: 20,itemBuilder: (context, index) {return Container(color: Colors.teal[100 * ((index % 8) 1)],alignment: Alignment.center,child: Text(Grid $index),);},
) GridView.extent指定最大宽度自动适配列数 GridView.extent(maxCrossAxisExtent: 100, // 每个项最大宽度系统自动决定多少列children: List.generate(20, (index) {return Container(alignment: Alignment.center,color: Colors.orange[100 * ((index % 8) 1)],child: Text(Item $index),);}),
) 常用属性说明 属性名类型说明crossAxisCountint每行显示的列数mainAxisSpacingdouble每行之间的间距垂直方向crossAxisSpacingdouble每列之间的间距水平方向childAspectRatiodouble宽高比宽/高shrinkWrapbool是否根据内容高度自适应适用于嵌套physicsScrollPhysics滚动行为常用于嵌套时禁用滚动 示例 import package:flutter/material.dart;class GridViewExample extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(GridView 示例)),body: GridView.builder(padding: EdgeInsets.all(10),gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, // 3列crossAxisSpacing: 10,mainAxisSpacing: 10,childAspectRatio: 1.0, // 宽高比 1:1),itemCount: 12,itemBuilder: (context, index) {return Container(color: Colors.blue[100 * ((index % 8) 1)],alignment: Alignment.center,child: Text(第 $index 项),);},),);}
} SingleChildScrollView单子节点滚动 SingleChildScrollView 允许一个子组件在主轴滚动通常是垂直 适用于控件数量不定时避免溢出overflow错误。 基本用法 SingleChildScrollView(child: Column(children: [Text(A),Text(B),Text(C),// 很多内容...],),
) SingleChildScrollView 的 child 只能是 一个 Widget通常搭配 Column 使用。 典型使用场景 登录页 / 注册页键盘弹出时防止布局溢出 表单页面需要整体滚动 多控件组合的页面不是列表 重要属性说明 属性名类型说明scrollDirectionAxis滚动方向默认是 Axis.verticalpaddingEdgeInsets内边距reversebool是否反向滚动physicsScrollPhysics滚动行为如弹性、不可滚动controllerScrollController控制滚动、监听滚动位置等 示例 import package:flutter/material.dart;class ScrollDemo extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(SingleChildScrollView 示例)),body: SingleChildScrollView(padding: EdgeInsets.all(16),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: List.generate(20, (index) {return Padding(padding: EdgeInsets.symmetric(vertical: 8),child: Text(第 $index 行文本内容));}),),),);}
} 与 ListView 区别对比 对比项SingleChildScrollViewListView用法场景多个固定控件、表单页面长列表、动态项性能优化没有懒加载所有内容一次性渲染支持懒加载子组件结构一个 Widget如 Column包多个控件多个 Widget 构建嵌套使用更适合嵌套在页面中或布局中嵌套需注意高度限制和滚动冲突
5.6 导航和路由 Navigator 介绍 Navigator 是用于管理页面Route跳转和堆栈操作的组件类似网页的前进、后退、跳转操作。 什么是 Navigator ? Navigator 是一个页面堆栈管理器你可以 push打开新页面入栈 pop返回上一个页面出栈 replace替换当前页面 清空所有页面再跳转跳转并清空历史 Navigator 通常配合 MaterialPageRoute 或 named route 使用。 最基础的页面跳转方式 跳转到新页面push Navigator.push(context,MaterialPageRoute(builder: (context) SecondPage()),
); 返回上一级页面pop Navigator.pop(context); 带返回值的页面跳转 A → BB返回数据给A 在 A 页面 void _goToSecondPage() async {final result await Navigator.push(context,MaterialPageRoute(builder: (context) SecondPage()),);print(从第二页返回的数据: $result);
} 在 B 页面 ElevatedButton(onPressed: () {Navigator.pop(context, 这是返回值);},child: Text(返回并携带数据),
) 使用命名路由推荐方式 定义路由表 MaterialApp(initialRoute: /,routes: {/: (context) HomePage(),/second: (context) SecondPage(),},
) 跳转方式 Navigator.pushNamed(context, /second); 返回方式 Navigator.pop(context); 常见跳转方式对比 跳转方式用法适合场景push()直接传入 Widget简单项目pushNamed()使用路由名称跳转大型项目统一管理路由pushReplacement()替换当前页面无返回登录成功替换登录页等pushAndRemoveUntil()清空历史再跳转登录后清空所有导航栈 小结 功能推荐方式普通页面跳转Navigator.push()命名路由跳转Navigator.pushNamed()页面返回携带数据Navigator.pop(context, result)替换页面不保留返回Navigator.pushReplacement()清空页面栈并跳转Navigator.pushAndRemoveUntil() push 和 pop push 和 pop 是 Flutter 中 Navigator 导航系统的两个最核心方法分别用于打开新页面和返回上一个页面就像“网页的前进和后退”。 Navigator.push() 作用** 打开压栈一个新页面** Navigator.push(context,MaterialPageRoute(builder: (context) SecondPage()),
);context当前页面的上下文 MaterialPageRoute常用的页面过渡动画安卓风格 SecondPage()你要跳转的新页面 Widget 示例 ElevatedButton(onPressed: () {Navigator.push(context,MaterialPageRoute(builder: (context) SecondPage()),);},child: Text(去第二页),
)Navigator.pop() 作用返回出栈上一个页面 Navigator.pop(context);可选地返回一个值 Navigator.pop(context, 返回的数据);push pop 结合使用带返回值 第一个页面 void _goToSecondPage() async {final result await Navigator.push(context,MaterialPageRoute(builder: (context) SecondPage()),);print(从第二页返回的数据是$result);
} 第二个页面 ElevatedButton(onPressed: () {Navigator.pop(context, 你好这是返回值);},child: Text(返回并传数据),
) Navigator 的“堆栈”原理图示 初始
[ HomePage ]push(SecondPage)
[ HomePage, SecondPage ]push(ThirdPage)
[ HomePage, SecondPage, ThirdPage ]pop()
[ HomePage, SecondPage ] push / pop 常见变体 方法名功能说明push()压入新页面pop()弹出当前页面pushReplacement()替换当前页面popUntil()返回到满足条件的页面pushAndRemoveUntil()清空页面栈并跳转 总结 功能方法打开新页面Navigator.push()返回上一页Navigator.pop()替换当前页面Navigator.pushReplacement()返回并带数据Navigator.pop(context, value)多页面返回条件Navigator.popUntil()
5.7 其他常用组件 AppBar应用栏 AppBar 是 Scaffold脚手架页面的顶部栏常用于显示页面标题title、返回按钮自动生成、操作按钮Icon、搜索框、TabBar、菜单等 它是 Flutter 应用中几乎每个页面都会使用的标准导航栏。 基本语法 Scaffold(appBar: AppBar(title: Text(我是标题),),body: Center(child: Text(内容)),
) 常用属性说明 属性名类型作用说明titleWidget应用栏的标题通常是 TextleadingWidget左侧图标默认是返回箭头actionsListWidget右侧图标按钮列表backgroundColorColor背景颜色centerTitlebool是否居中标题iOS 默认为 trueelevationdouble阴影高度默认 4bottomPreferredSizeWidget下方扩展区域如 TabBar 示例 import package:flutter/material.dart;class AppBarExample extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(AppBar 示例),leading: Icon(Icons.menu),actions: [IconButton(icon: Icon(Icons.search),onPressed: () {print(搜索按钮点击);},),IconButton(icon: Icon(Icons.more_vert),onPressed: () {print(更多菜单);},),],),body: Center(child: Text(页面内容区域),),);}
} Scaffold脚手架基础页面布局 Scaffold 是 Flutter 提供的 页面结构容器提供了一个基本布局框架包含AppBar顶部应用栏、Body主要内容区、Drawer侧边栏、BottomNavigationBar底部导航、FloatingActionButton悬浮按钮 、SnackBar轻提示等。它就像“页面的骨架”你把各种 UI 部件放进去就可以构成完整的页面。 基本使用方式 Scaffold(appBar: AppBar(title: Text(首页)),body: Center(child: Text(Hello World)),
)Scaffold 的常用属性详解 属性名类型作用说明appBarAppBar页面顶部导航栏bodyWidget页面主要内容区域floatingActionButtonFloatingActionButton页面悬浮按钮drawerDrawer左侧滑出菜单bottomNavigationBarBottomNavigationBar页面底部导航栏backgroundColorColor页面背景色persistentFooterButtonsListWidget固定在底部的按钮组bottomSheetWidget页面底部悬浮层 示例 import package:flutter/material.dart;class ScaffoldExample extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Scaffold 示例)),body: Center(child: Text(我是页面内容)),floatingActionButton: FloatingActionButton(onPressed: () {ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(你点击了按钮)),);},child: Icon(Icons.add),),drawer: Drawer(child: ListView(children: [DrawerHeader(decoration: BoxDecoration(color: Colors.blue),child: Text(菜单头部, style: TextStyle(color: Colors.white))),ListTile(title: Text(选项1)),ListTile(title: Text(选项2))],),),bottomNavigationBar: BottomAppBar(child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: [IconButton(onPressed: (){}, icon: Icon(Icons.home)),IconButton(onPressed: (){}, icon: Icon(Icons.person))],),),);}
} 常见组合搭配 页面需求Scaffold 结构用法普通页面顶部内容appBar body带悬浮操作按钮floatingActionButton左侧菜单导航drawer底部固定菜单栏bottomNavigationBar or BottomAppBar显示提示ScaffoldMessenger.of(context).showSnackBar(...) Drawer抽屉导航 Drawer 是 Scaffold 提供的一个侧边导航菜单通常从左边滑出用于展示导航选项、用户信息等。 基本结构 Drawer(child: ListView(padding: EdgeInsets.zero,children: [DrawerHeader(decoration: BoxDecoration(color: Colors.blue),child: Text(用户信息),),ListTile(leading: Icon(Icons.home),title: Text(首页),onTap: () {// 点击事件},),ListTile(leading: Icon(Icons.settings),title: Text(设置),onTap: () {// 点击事件},),],),
) Drawer 常用组件说明 组件作用DrawerHeader抽屉顶部区域一般用于展示用户头像、昵称ListTile列表项一般用于菜单选项ListView内容可滚动 打开与关闭 Drawer 自动打开 用户手动左滑 点左上角菜单按钮如果 AppBar 中设置了 automaticallyImplyLeading: true 手动打开 Scaffold.of(context).openDrawer(); // 仅限于在子 Widget 中使用 Builder 包裹手动关闭 Navigator.pop(context)示例 class DrawerExample extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Drawer 示例)),drawer: Drawer(child: ListView(padding: EdgeInsets.zero,children: [const UserAccountsDrawerHeader(accountName: Text(张三),accountEmail: Text(zhangsanexample.com),currentAccountPicture: CircleAvatar(backgroundImage: AssetImage(assets/images/ic_launcher.png),),),ListTile(leading: const Icon(Icons.home),title: const Text(首页),onTap: () {Navigator.pop(context);},),ListTile(leading: const Icon(Icons.settings),title: const Text(设置),onTap: () {Navigator.pop(context);},),],),),body: const Center(child: Text(主页面内容)));}
} 小结 你要实现的功能推荐做法左侧菜单导航使用 Scaffold.drawer右侧快捷操作菜单使用 Scaffold.endDrawer展示用户头像信息使用 UserAccountsDrawerHeader菜单点击关闭并跳转先 Navigator.pop() 再导航页面 BottomNavigationBar底部导航栏 BottomNavigationBar 是 Flutter 提供的一个底部导航栏组件配合 Scaffold 使用支持多个标签切换视图页面。 它可以 显示多个 tab 标签一般 3 ~ 5 个高亮当前选中项点击切换页面配合 IndexedStack) 基本用法 Scaffold(bottomNavigationBar: BottomNavigationBar(currentIndex: 0, // 当前选中索引onTap: (index) {// 切换页面逻辑},items: [BottomNavigationBarItem(icon: Icon(Icons.home),label: 首页,),BottomNavigationBarItem(icon: Icon(Icons.person),label: 我的,),],),
) 示例 import package:flutter/material.dart;class BottomNavExample extends StatefulWidget {override_BottomNavExampleState createState() _BottomNavExampleState();
}class _BottomNavExampleState extends StateBottomNavExample {int _currentIndex 0;final ListWidget _pages [Center(child: Text(首页内容)),Center(child: Text(分类内容)),Center(child: Text(我的内容))];overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(底部导航示例)),body: IndexedStack (index: _currentIndex,children: _pages,),bottomNavigationBar: BottomNavigationBar (currentIndex: _currentIndex,onTap: (index) {setState(() {_currentIndex index;});},items: [BottomNavigationBarItem(icon: Icon(Icons.home), label: 首页),BottomNavigationBarItem(icon: Icon(Icons.category), label: 分类),BottomNavigationBarItem(icon: Icon(Icons.person), label: 我的),],),);}
} 属性说明 属性名类型说明itemsList菜单项最少2项currentIndexint当前选中项的索引onTapFunction(int)点击导航项回调typeBottomNavigationBarType显示样式fixed默认或 shifting动效selectedItemColorColor选中项颜色unselectedItemColorColor未选中项颜色backgroundColorColor背景色
6. 状态管理基础
6.1 什么是状态
简单来说状态就是某个变量的值 当这个值发生变化时对应的 UI会自动刷新 展示新的内容
比如 一个计数器的数字是状态 count 3) 一个按钮是否选中是状态isSelected true 一个页面当前是“加载中”还是“已完成”是状态loading true / false
示例
int count 0; // 这就是一个状态ElevatedButton(onPressed: () {setState(() {count;});},child: Text(点击了 $count 次),
) Flutter 中状态是怎么驱动 UI 的 Flutter 的 Widget 是声明时UI它不是手动改动控件而是重新构建 // 当状态改变时
setState((){count; // 修改状态
});
// Flutter 自动重新调用 build() - 根据新状态更新 UI这就是 Flutter 的核心机制 状态驱动UI 状态在哪些 Widget 中存在 Widget 类型状态管理方式StatelessWidget无状态固定不变的 UI只能显示数据StatefulWidget有状态可变 UI状态变化会自动刷新 常见状态的例子 场景状态变量计数器int counter登录表单String username, password切换主题bool isDarkMode是否选中某项bool isChecked当前页面索引int currentIndex
7. 资源管理 图片资源的使用 在 Flutter 中使用图片资源是构建 UI 的基本技能之一分为以下几类资源使用方式 Flutter 中的图片来源类型 图片来源示例使用方式本地 assets项目中的 assets/images/Image.asset(...)网络图片网络链接Image.network(...)内存 / 字节流Uint8List 数据Image.memory(...)文件系统图片本地文件路径Image.file(...) 使用本地图片assets) 步骤一创建 assets 目录 在项目根目录下创建文件夹 /assets/images/放入图片例如 assets/images/logo.png步骤二配置 pubspec.yaml 打开 pubspec.yaml 添加以下内容并取消注释缩进对齐 flutter:uses-material-design: trueassets:- assets/images/logo.png# 或包含整个文件夹# - assets/images/注意 缩进要使用空格不能用 Tab 图片路径对大小写敏感 步骤三使用 Image.asset 显示图片 Image.asset(assets/images/logo.png,width: 200,height: 100,fit: BoxFit.cover, // 控制缩放裁剪方式
)使用网络图片Image.network) Image.network(https://flutter.dev/images/flutter-logo-sharing.png,width: 200,height: 100,fit: BoxFit.contain,loadingBuilder: (context, child, progress) {if (progress null) return child;return CircularProgressIndicator();},errorBuilder: (context, error, stackTrace) {return Icon(Icons.error);},
)建议总是配 loadingBuilder 和 errorBuilder 处理网络情况。 图片控件常用属性 属性名类型说明widthdouble图片宽度heightdouble图片高度fitBoxFit图片缩放裁剪方式如 contain、covercolorColor给图片加上颜色遮罩配合 colorBlendModerepeatImageRepeat图片重复方式如 repeat-xalignmentAlignment图片对齐方式 图片裁剪、圆形、边框示例 圆形头像 ClipOval(child: Image.asset(assets/images/avatar.jpg,width: 100,height: 100,fit: BoxFit.cover,),
)圆角图片 ClipRRect(borderRadius: BorderRadius.circular(12),child: Image.asset(assets/images/banner.jpg),
)示例 class ImageExample extends StatelessWidget {overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(图片示例)),body: Column(children: [Text(本地图片),Image.asset(assets/images/ic_launcher.png, width: 100),SizedBox(height: 20),Text(网络图片),Image.network(https://www.163987.com/d/file/p/2023/05-12/01f170d69eace10455c7116e98290099.png,width: 100)],));}
} 总结 目标方法加载项目中的图片Image.asset(路径)加载网络图片Image.network(url)加载本地文件图片Image.file(File(路径))加载内存字节图片Image.memory(Uint8List) 字体和图标配置 使用字体 步骤一添加字体文件 在项目中创建字体目录 assets/fonts/放入字体文件例如 assets/fonts/Pacifico-Regular.ttf步骤二配置 pubspec.yaml 在 flutter: 区块下添加字体配置注意缩进 flutter:uses-material-design: truefonts:- family: Pacificofonts:- asset: assets/fonts/Pacifico-Regular.ttf 步骤三使用字体 Text(Hello 字体,style: TextStyle(fontFamily: Pacifico,fontSize: 32,),
)使用内置图标Material Icons Flutter 默认包含 Material Icons 图标库只要 flutter:uses-material-design: true即可使用 Icon(Icons.favorite, color: Colors.red)pubspec.yaml 中资源声明 Flutter 中的 assets 是项目中包含的静态资源例如 图片PNG、JPG、SVG 音频MP3、WAV 字体文件TTF JSON / 文本 / 配置文件等 这些资源 必须在 pubspec.yaml 中显式声明 才能在应用中使用。 声明单个文件 flutter:assets:- assets/images/logo.png声明整个文件夹 flutter:assets:- assets/images/- assets/audio/注意事项 项说明缩进必须是 2 个空格不能用 Tab区分大小写logo.PNG ≠ logo.png文件路径必须真实存在拼写要对不支持通配不能写成 assets/images/*.png只能手动列出或列目录修改后需每次更改 assets 配置都应运行 flutter pub get 或重启 IDE 使其生效