📚 目录
Widget 基础概念
什么是 Widget?
Widget 是 Flutter 应用的基础构建块。在 Flutter 中,一切都是 Widget!
- Widget 是配置对象:它们描述了用户界面的一部分应该如何显示
- Widget 是不可变的(Immutable):一旦创建,其属性就不能改变
- Widget 是轻量级的:它们只是配置信息,不是实际的渲染对象
- Widget 树:所有 Widget 组成一个树形结构,描述了整个 UI 的层次关系
Widget 的核心特性
-
不可变性(Immutability)
- Widget 一旦创建就不能修改
- 要更新 UI,需要创建新的 Widget
- 这确保了 UI 的一致性和可预测性
-
组合性(Composition)
- Widget 可以嵌套其他 Widget
- 通过组合简单的 Widget 来构建复杂的 UI
-
声明式编程(Declarative)
- 你描述 UI 应该是什么样子,而不是如何构建它
- Flutter 框架负责实际的渲染工作
Widget 的类型
1. StatelessWidget(无状态 Widget)
特点:
- 一旦创建,其属性就不能改变
- 不持有可变的状态
- 适用于静态内容或只依赖于传入参数的内容
使用场景:
- 显示静态文本
- 展示图片
- 简单的布局容器
- 不需要用户交互的 UI 元素
示例:
class MyText extends StatelessWidget {
final String text;
const MyText({super.key, required this.text});
@override
Widget build(BuildContext context) {
return Text(text);
}
}
2. StatefulWidget(有状态 Widget)
特点:
- 可以持有可变的状态
- 当状态改变时,会调用
setState()重新构建 UI - 由两部分组成:Widget 类和 State 类
使用场景:
- 需要用户交互的界面
- 需要根据数据变化更新的 UI
- 表单输入
- 动画效果
示例:
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('计数: $_count'),
ElevatedButton(
onPressed: _increment,
child: const Text('增加'),
),
],
);
}
}
重要概念:
-
setState():通知 Flutter 状态已改变,需要重新构建 Widget - State 对象在 Widget 重建时会被保留
- State 对象可以持有可变的数据
常用 Widget 详解
应用入口 Widget
MaterialApp(Android 风格应用)
- 用途:Android 风格应用的根 Widget,提供主题、路由、本地化等功能
-
详细属性:
-
title:应用标题(String),用于任务管理器显示 -
home:应用启动时显示的主页面(Widget) -
theme:应用主题(ThemeData),定义颜色、字体、组件样式等 -
darkTheme:深色主题(ThemeData) -
themeMode:主题模式(ThemeMode):system、light、dark -
routes:命名路由表(Map<String, WidgetBuilder>) -
initialRoute:初始路由名称(String) -
onGenerateRoute:路由生成器(RouteFactory) -
onUnknownRoute:未知路由处理器(RouteFactory) -
locale:当前语言环境(Locale) -
supportedLocales:支持的语言环境列表(List<Locale>) -
localizationsDelegates:本地化代理列表 -
debugShowCheckedModeBanner:是否显示右上角调试横幅(bool,默认 true) -
color:应用主色(Color),用于系统 UI -
builder:构建器函数,用于包装整个应用 -
navigatorKey:导航器键(GlobalKey<NavigatorState>) -
navigatorObservers:导航器观察者列表 -
scaffoldMessengerKey:ScaffoldMessenger 的键
-
-
示例:
MaterialApp( title: '我的应用', theme: ThemeData( primarySwatch: Colors.blue, useMaterial3: true, ), darkTheme: ThemeData.dark(), themeMode: ThemeMode.system, home: const HomePage(), routes: { '/home': (context) => const HomePage(), '/settings': (context) => const SettingsPage(), }, debugShowCheckedModeBanner: false, );
CupertinoApp(iOS 风格应用)
- 用途:iOS 风格应用的根 Widget,提供 iOS 风格的组件和主题
-
详细属性:
-
title:应用标题(String) -
home:应用启动时显示的主页面(Widget) -
theme:Cupertino 主题(CupertinoThemeData) -
routes:命名路由表(Map<String, WidgetBuilder>) -
initialRoute:初始路由名称(String) -
onGenerateRoute:路由生成器(RouteFactory) -
onUnknownRoute:未知路由处理器(RouteFactory) -
locale:当前语言环境(Locale) -
supportedLocales:支持的语言环境列表(List<Locale>) -
localizationsDelegates:本地化代理列表 -
debugShowCheckedModeBanner:是否显示调试横幅(bool) -
color:应用主色(Color) -
builder:构建器函数 -
navigatorKey:导航器键 -
navigatorObservers:导航器观察者列表
-
-
示例:
CupertinoApp( title: 'iOS 风格应用', theme: const CupertinoThemeData( primaryColor: CupertinoColors.systemBlue, brightness: Brightness.light, ), home: const HomePage(), debugShowCheckedModeBanner: false, ); -
MaterialApp vs CupertinoApp:
- MaterialApp:Android Material Design 风格
- CupertinoApp:iOS Cupertino 风格
- 若需实现 “Android 用 Material,iOS 用 Cupertino” 的自适应效果:可通过 Platform.isIOS 动态判断平台,选择对应的顶层容器
- 示例:
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; void main() { runApp( Platform.isIOS ? CupertinoApp(home: IosHomePage()) // iOS 用 CupertinoApp : MaterialApp(home: AndroidHomePage()) // Android 用 MaterialApp ); }
Scaffold(页面骨架)
-
用途:整个页面的基础布局框架,提供
AppBar、Drawer、FloatingActionButton等常见布局位置 -
详细属性:
-
appBar:顶部应用栏(PreferredSizeWidget?) -
body:页面主体内容(Widget?) -
floatingActionButton:浮动按钮(Widget?) -
floatingActionButtonLocation:浮动按钮位置(FloatingActionButtonLocation?) -
floatingActionButtonAnimator:浮动按钮动画器(FloatingActionButtonAnimator?) -
persistentFooterButtons:持久底部按钮列表(List<Widget>?) -
drawer:左侧抽屉(Widget?) -
endDrawer:右侧抽屉(Widget?) -
bottomNavigationBar:底部导航栏(Widget?) -
bottomSheet:底部表单(Widget?) -
backgroundColor:背景色(Color?) -
resizeToAvoidBottomInset:是否调整大小避免底部插入(bool?) -
primary:是否为主应用栏(bool?) -
drawerDragStartBehavior:抽屉拖拽开始行为(DragStartBehavior) -
extendBody:是否扩展主体(bool) -
extendBodyBehindAppBar:是否在 AppBar 后扩展主体(bool) -
drawerScrimColor:抽屉遮罩颜色(Color?) -
drawerEdgeDragWidth:抽屉边缘拖拽宽度(double?) -
drawerEnableOpenDragGesture:是否启用抽屉打开手势(bool) -
endDrawerEnableOpenDragGesture:是否启用右侧抽屉打开手势(bool) -
restorationId:恢复 ID(String?)
-
-
示例:
Scaffold( appBar: AppBar( title: const Text('Scaffold 示例'), actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () {}, ), ], ), body: const Center(child: Text('这里是主体内容')), floatingActionButton: FloatingActionButton( onPressed: () {}, child: const Icon(Icons.add), ), drawer: const Drawer( child: Center(child: Text('左侧抽屉菜单')), ), bottomNavigationBar: BottomNavigationBar( items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'), BottomNavigationBarItem(icon: Icon(Icons.settings), label: '设置'), ], ), );
AppBar(应用栏)
- 用途:页面顶部的标题栏,通常放标题、操作按钮、Tab 等
-
详细属性:
-
title:主标题(Widget),常用Text -
leading:左侧按钮(Widget?),通常是返回按钮或菜单按钮 -
actions:右侧动作按钮列表(List<Widget>?) -
backgroundColor:背景色(Color?) -
foregroundColor:前景色(Color?) -
elevation:阴影高度(double?) -
shadowColor:阴影颜色(Color?) -
iconTheme:图标主题(IconThemeData?) -
actionsIconTheme:动作图标主题(IconThemeData?) -
textTheme:文本主题(TextTheme?) -
centerTitle:是否居中标题(bool?) -
titleSpacing:标题间距(double?) -
toolbarHeight:工具栏高度(double?) -
toolbarOpacity:工具栏透明度(double?) -
bottom:底部 Widget(PreferredSizeWidget?),常用于 TabBar -
flexibleSpace:灵活空间(Widget?) -
brightness:亮度(Brightness?) -
automaticallyImplyLeading:是否自动显示 leading(bool?) -
primary:是否为主应用栏(bool?) -
excludeHeaderSemantics:是否排除头部语义(bool?) -
toolbarTextStyle:工具栏文本样式(TextStyle?) -
titleTextStyle:标题文本样式(TextStyle?) -
systemOverlayStyle:系统覆盖层样式(SystemUiOverlayStyle?)
-
-
示例:
AppBar( title: const Text('Widget 学习'), leading: IconButton( icon: const Icon(Icons.menu), onPressed: () {}, ), actions: [ IconButton( icon: const Icon(Icons.notifications), onPressed: () {}, ), IconButton( icon: const Icon(Icons.account_circle), onPressed: () {}, ), ], centerTitle: true, backgroundColor: Colors.indigo, elevation: 4, );
布局 Widget
1. Container(容器)
- 用途:最常用的布局 Widget,可以设置尺寸、内边距、外边距、装饰等
-
详细属性:
-
child:子 Widget(Widget) -
alignment:子 Widget 对齐方式(AlignmentGeometry) -
padding:内边距(EdgeInsetsGeometry) -
margin:外边距(EdgeInsetsGeometry) -
width:宽度(double) -
height:高度(double) -
constraints:布局约束(BoxConstraints) -
decoration:装饰(BoxDecoration)-
color:背景色 -
image:背景图片 -
border:边框(Border) -
borderRadius:圆角(BorderRadius) -
boxShadow:阴影列表(List<BoxShadow>) -
gradient:渐变(Gradient) -
shape:形状(BoxShape):rectangle、circle
-
-
foregroundDecoration:前景装饰(Decoration) -
transform:变换矩阵(Matrix4) -
clipBehavior:裁剪行为(Clip)
-
-
示例:
Container( width: 200, height: 100, padding: const EdgeInsets.all(16), margin: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.black, width: 2), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.5), spreadRadius: 2, blurRadius: 5, offset: const Offset(0, 3), ), ], ), child: const Text('容器内容'), );
2. Row(行)
- 用途:水平排列子 Widget
-
详细属性:
-
children:子 Widget 列表(List<Widget>) -
mainAxisAlignment:主轴对齐方式(MainAxisAlignment)-
start:开始对齐 -
end:结束对齐 -
center:居中对齐 -
spaceBetween:两端对齐,中间均匀分布 -
spaceAround:均匀分布,两端有间距 -
spaceEvenly:均匀分布,包括两端
-
-
crossAxisAlignment:交叉轴对齐方式(CrossAxisAlignment)-
start:开始对齐 -
end:结束对齐 -
center:居中对齐 -
stretch:拉伸填充 -
baseline:基线对齐
-
-
mainAxisSize:主轴尺寸(MainAxisSize):min、max -
textDirection:文本方向(TextDirection):ltr、rtl -
verticalDirection:垂直方向(VerticalDirection):down、up -
textBaseline:文本基线(TextBaseline)
-
-
示例:
Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container(width: 50, height: 50, color: Colors.red), Container(width: 50, height: 50, color: Colors.green), Container(width: 50, height: 50, color: Colors.blue), ], );
3. Column(列)
- 用途:垂直排列子 Widget
- 详细属性:与 Row 相同,但主轴和交叉轴互换
-
示例:
Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container(width: 50, height: 50, color: Colors.red), Container(width: 50, height: 50, color: Colors.green), Container(width: 50, height: 50, color: Colors.blue), ], );
4. Stack(堆叠)
- 用途:将 Widget 叠加在一起
-
详细属性:
-
children:子 Widget 列表(List<Widget>),后面的在上层 -
alignment:对齐方式(AlignmentGeometry),默认AlignmentDirectional.topStart -
fit:子 Widget 的适应方式(StackFit)-
loose:宽松适应 -
expand:扩展填充 -
passthrough:传递约束
-
-
clipBehavior:裁剪行为(Clip):none、hardEdge、antiAlias、antiAliasWithSaveLayer -
textDirection:文本方向(TextDirection)
-
-
示例:
Stack( alignment: Alignment.center, children: [ Container(width: 200, height: 200, color: Colors.blue), Container(width: 100, height: 100, color: Colors.red.withOpacity(0.7)), const Text('Stack 示例'), ], );
5. Expanded(扩展)
- 用途:在 Row 或 Column 中占用剩余空间
-
详细属性:
-
child:子 Widget(Widget) -
flex:占用比例(int),默认为 1
-
-
示例:
Row( children: [ Expanded( flex: 1, child: Container(height: 100, color: Colors.red), ), Expanded( flex: 2, child: Container(height: 100, color: Colors.blue), ), ], );
6. Flexible(灵活)
- 用途:类似 Expanded,但不强制填充所有空间
-
详细属性:
-
child:子 Widget(Widget) -
flex:占用比例(int),默认为 1 -
fit:适应方式(FlexFit):tight(紧密,类似 Expanded)、loose(宽松)
-
-
示例:
Row( children: [ Flexible( flex: 1, fit: FlexFit.loose, child: Container(height: 100, color: Colors.green), ), Flexible( flex: 2, fit: FlexFit.loose, child: Container(height: 100, color: Colors.orange), ), ], );
7. SizedBox(固定尺寸盒子)
- 用途:固定尺寸的容器,也常用于添加间距
-
详细属性:
-
width:宽度(double) -
height:高度(double) -
child:子 Widget(Widget)
-
-
示例:
SizedBox( width: 200, height: 100, child: const Text('固定尺寸'), ); // 用作间距 const SizedBox(height: 20); const SizedBox(width: 10);
8. Padding(内边距)
- 用途:添加内边距
-
详细属性:
-
padding:内边距(EdgeInsetsGeometry)-
EdgeInsets.all(20):所有方向 -
EdgeInsets.symmetric(horizontal: 20, vertical: 10):对称 -
EdgeInsets.only(left: 10, top: 20, right: 10, bottom: 20):各方向不同
-
-
child:子 Widget(Widget)
-
-
示例:
Padding( padding: const EdgeInsets.all(20), child: Container(color: Colors.blue, child: const Text('带内边距')), );
9. Center(居中)
- 用途:将子 Widget 居中
-
详细属性:
-
child:子 Widget(Widget) -
widthFactor:宽度因子(double),如果设置,宽度 = 子 Widget 宽度 × widthFactor -
heightFactor:高度因子(double),如果设置,高度 = 子 Widget 高度 × heightFactor
-
-
示例:
Center( child: Container( width: 100, height: 100, color: Colors.purple, ), );
10. Wrap(自动换行)
- 用途:自动换行的布局,类似 Row/Column 但可以换行
-
详细属性:
-
children:子 Widget 列表(List<Widget>) -
direction:方向(Axis):horizontal、vertical -
alignment:对齐方式(WrapAlignment) -
spacing:主轴间距(double) -
runSpacing:交叉轴间距(double) -
crossAxisAlignment:交叉轴对齐方式(WrapCrossAlignment) -
textDirection:文本方向(TextDirection) -
verticalDirection:垂直方向(VerticalDirection)
-
-
示例:
Wrap( spacing: 8, runSpacing: 8, children: List.generate(10, (index) { return Chip( label: Text('标签 $index'), ); }), );
文本 Widget
Text(文本)
- 用途:显示文本
-
详细属性:
-
data:文本内容(String) -
style:文本样式(TextStyle)-
fontSize:字体大小(double) -
fontWeight:字体粗细(FontWeight):normal、bold、w100-w900 -
fontStyle:字体样式(FontStyle):normal、italic -
color:文字颜色(Color) -
backgroundColor:背景色(Color) -
letterSpacing:字符间距(double) -
wordSpacing:单词间距(double) -
height:行高(double) -
decoration:文本装饰(TextDecoration):none、underline、overline、lineThrough -
decorationColor:装饰颜色(Color) -
decorationStyle:装饰样式(TextDecorationStyle) -
fontFamily:字体家族(String)
-
-
textAlign:文本对齐(TextAlign):left、right、center、justify、start、end -
textDirection:文本方向(TextDirection) -
maxLines:最大行数(int) -
overflow:溢出处理(TextOverflow):clip、fade、ellipsis、visible -
textScaleFactor:文本缩放因子(double) -
semanticsLabel:语义标签(String),用于无障碍 -
softWrap:是否自动换行(bool) -
textWidthBasis:文本宽度基础(TextWidthBasis)
-
-
示例:
Text( '这是文本示例', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.blue, decoration: TextDecoration.underline, ), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, );
按钮 Widget
ElevatedButton(凸起按钮)
- 用途:有阴影的按钮,适合主要操作
-
详细属性:
-
onPressed:点击回调(VoidCallback?),为 null 时按钮禁用 -
onLongPress:长按回调(VoidCallback?) -
child:子 Widget(Widget),通常是 Text 或 Icon -
style:按钮样式(ButtonStyle) -
autofocus:是否自动聚焦(bool) -
clipBehavior:裁剪行为(Clip)
-
-
示例:
ElevatedButton( onPressed: () { print('按钮被点击'); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text('凸起按钮'), );
TextButton(文本按钮)
- 用途:扁平按钮,适合次要操作
- 详细属性:与 ElevatedButton 相同
-
示例:
TextButton( onPressed: () {}, child: const Text('文本按钮'), );
OutlinedButton(轮廓按钮)
- 用途:有边框的按钮
- 详细属性:与 ElevatedButton 相同
-
示例:
OutlinedButton( onPressed: () {}, child: const Text('轮廓按钮'), );
IconButton(图标按钮)
- 用途:只显示图标的按钮
-
详细属性:
-
icon:图标(Widget),通常是 Icon -
onPressed:点击回调(VoidCallback?) -
onLongPress:长按回调(VoidCallback?) -
iconSize:图标大小(double) -
color:图标颜色(Color?) -
disabledColor:禁用时颜色(Color?) -
tooltip:工具提示(String?) -
autofocus:是否自动聚焦(bool) -
focusNode:焦点节点(FocusNode?) -
constraints:约束(BoxConstraints?) -
style:按钮样式(ButtonStyle?)
-
-
示例:
IconButton( icon: const Icon(Icons.favorite), onPressed: () {}, iconSize: 30, color: Colors.red, tooltip: '收藏', );
输入 Widget
TextField(文本输入框)
- 用途:单行文本输入
-
详细属性:
-
controller:文本控制器(TextEditingController?) -
decoration:输入框装饰(InputDecoration?)-
labelText:标签文本 -
hintText:提示文本 -
helperText:帮助文本 -
errorText:错误文本 -
prefixIcon:前缀图标 -
suffixIcon:后缀图标 -
border:边框样式 -
filled:是否填充背景 -
fillColor:填充颜色
-
-
onChanged:文本改变时的回调(ValueChanged<String>?) -
onSubmitted:提交时的回调(ValueChanged<String>?) -
keyboardType:键盘类型(TextInputType) -
textInputAction:输入动作(TextInputAction) -
obscureText:是否隐藏文本(bool),用于密码输入 -
maxLines:最大行数(int),默认为 1 -
maxLength:最大长度(int?) -
enabled:是否启用(bool) -
readOnly:是否只读(bool) -
autofocus:是否自动聚焦(bool) -
style:文本样式(TextStyle?) -
textAlign:文本对齐(TextAlign) -
textCapitalization:文本大写(TextCapitalization)
-
-
示例:
TextField( controller: TextEditingController(), decoration: const InputDecoration( labelText: '用户名', hintText: '请输入用户名', prefixIcon: Icon(Icons.person), border: OutlineInputBorder(), ), onChanged: (value) { print('输入内容: $value'); }, keyboardType: TextInputType.text, );
TextFormField(表单输入框)
- 用途:带验证的表单输入
-
详细属性:继承 TextField 的所有属性,额外包括:
-
validator:验证函数(FormFieldValidator<String>?) -
autovalidateMode:自动验证模式(AutovalidateMode?) -
onSaved:保存时的回调(FormFieldSetter<String>?)
-
-
示例:
TextFormField( decoration: const InputDecoration( labelText: '邮箱', border: OutlineInputBorder(), ), validator: (value) { if (value == null || value.isEmpty) { return '请输入邮箱'; } if (!value.contains('@')) { return '邮箱格式不正确'; } return null; }, autovalidateMode: AutovalidateMode.onUserInteraction, );
列表 Widget
ListView(列表视图)
- 用途:可滚动的列表
-
详细属性:
-
children:子 Widget 列表(List<Widget>),用于 ListView() -
itemBuilder:列表项构建器(IndexedWidgetBuilder?),用于 ListView.builder() -
itemCount:列表项数量(int?),用于 ListView.builder() -
separatorBuilder:分隔符构建器(IndexedWidgetBuilder?),用于 ListView.separated() -
scrollDirection:滚动方向(Axis):vertical、horizontal -
reverse:是否反向滚动(bool) -
controller:滚动控制器(ScrollController?) -
physics:滚动物理效果(ScrollPhysics?) -
padding:内边距(EdgeInsetsGeometry?) -
shrinkWrap:是否收缩包装(bool) -
cacheExtent:缓存范围(double?)
-
-
变体:
-
ListView():直接创建列表项,适合少量固定项 -
ListView.builder():懒加载,性能更好,适合大量动态项 -
ListView.separated():带分隔符的列表
-
-
示例:
// ListView ListView( children: [ ListTile(title: Text('项目 1')), ListTile(title: Text('项目 2')), ], ); // ListView.builder ListView.builder( itemCount: 100, itemBuilder: (context, index) { return ListTile(title: Text('项目 ${index + 1}')); }, ); // ListView.separated ListView.separated( itemCount: 10, separatorBuilder: (context, index) => const Divider(), itemBuilder: (context, index) { return ListTile(title: Text('项目 ${index + 1}')); }, );
其他常用 Widget
Card(卡片)
- 用途:带阴影和圆角的容器
-
详细属性:
-
child:子 Widget(Widget) -
elevation:阴影高度(double),默认 1.0 -
margin:外边距(EdgeInsetsGeometry?) -
shape:形状(ShapeBorder?) -
color:背景色(Color?) -
shadowColor:阴影颜色(Color?) -
clipBehavior:裁剪行为(Clip)
-
-
示例:
Card( elevation: 5, margin: const EdgeInsets.all(16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: const ListTile( title: Text('卡片标题'), subtitle: Text('卡片内容'), ), );
Icon(图标)
- 用途:显示 Material Design 图标
-
详细属性:
-
icon:图标数据(IconData) -
size:图标大小(double?),默认 24.0 -
color:图标颜色(Color?) -
semanticLabel:语义标签(String?) -
textDirection:文本方向(TextDirection?)
-
-
示例:
Icon( Icons.favorite, size: 40, color: Colors.red, );
Image(图片)
- 用途:显示图片(网络、本地、资源)
-
详细属性:
-
image:图片提供者(ImageProvider) -
width:宽度(double?) -
height:高度(double?) -
fit:适应方式(BoxFit)-
fill:填充 -
contain:包含 -
cover:覆盖 -
fitWidth:适应宽度 -
fitHeight:适应高度 -
none:不缩放 -
scaleDown:缩小
-
-
alignment:对齐方式(AlignmentGeometry) -
repeat:重复方式(ImageRepeat) -
loadingBuilder:加载构建器(ImageLoadingBuilder?) -
errorBuilder:错误构建器(ImageErrorWidgetBuilder?) -
frameBuilder:帧构建器(ImageFrameBuilder?) -
semanticLabel:语义标签(String?)
-
-
创建方式:
-
Image.network():网络图片 -
Image.asset():资源图片 -
Image.file():本地文件 -
Image.memory():内存图片
-
-
示例:
Image.network( 'https://example.com/image.jpg', width: 200, height: 200, fit: BoxFit.cover, loadingBuilder: (context, child, progress) { if (progress == null) return child; return const CircularProgressIndicator(); }, errorBuilder: (context, error, stackTrace) { return const Icon(Icons.error); }, );
Widget 生命周期
StatelessWidget 生命周期
- 创建:Widget 被创建
- build():构建 Widget 树
- 销毁:Widget 从树中移除
StatefulWidget 生命周期
- createState():创建 State 对象
- initState():State 对象初始化(只调用一次)
- didChangeDependencies():依赖改变时调用
- build():构建 Widget 树(可能多次调用)
- setState():状态改变,触发重建
- didUpdateWidget():Widget 配置更新时调用
- deactivate():State 对象从树中移除时调用
- dispose():State 对象被永久销毁时调用(清理资源)
重要方法:
-
initState():初始化数据、订阅流等 -
dispose():取消订阅、释放资源等
最佳实践
1. 使用 const 构造函数
// ✅ 好的做法
const Text('Hello');
// ❌ 避免
Text('Hello');
2. 合理使用 StatelessWidget 和 StatefulWidget
- 如果不需要状态,使用 StatelessWidget
- 只有在需要可变状态时才使用 StatefulWidget
3. 提取 Widget
- 将复杂的 Widget 拆分成小的、可复用的 Widget
- 提高代码可读性和可维护性
4. 使用 Key
- 在列表中使用 Key 帮助 Flutter 识别 Widget
- 特别是在动态列表中
5. 避免在 build() 中做耗时操作
- build() 方法应该只负责构建 UI
- 耗时操作应该在 initState() 或其他生命周期方法中执行
6. 正确使用 setState()
- 只在需要更新 UI 时调用 setState()
- 不要在 build() 方法中调用 setState()
7. 管理资源
- 在 dispose() 中释放资源(控制器、订阅等)
- 避免内存泄漏