Appearance
Flutter Widget系统 #
Flutter的Widget系统是其核心架构,一切UI元素都是Widget。理解Widget系统对于掌握Flutter开发至关重要。本章将详细介绍Widget系统的核心概念、类型和使用方法。
Widget系统基础 #
Widget、Element和RenderObject的关系 #
在Flutter中,有三个核心概念:Widget、Element和RenderObject,它们共同构成了Flutter的UI系统。
dart
// Widget示例 - 描述UI配置
class MyButton extends StatelessWidget {
final String text;
final VoidCallback onPressed;
const MyButton({
Key? key,
required this.text,
required this.onPressed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPressed,
child: Container(
padding: EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8.0),
),
child: Text(
text,
style: TextStyle(color: Colors.white),
),
),
);
}
}
// Widget的构建过程演示
class WidgetBuildDemo extends StatefulWidget {
@override
_WidgetBuildDemoState createState() => _WidgetBuildDemoState();
}
class _WidgetBuildDemoState extends State<WidgetBuildDemo> {
int counter = 0;
@override
Widget build(BuildContext context) {
print('build() called'); // 每次setState都会调用
return Scaffold(
appBar: AppBar(title: Text('Widget Build Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter: $counter'),
SizedBox(height: 20),
MyButton(
text: 'Increment',
onPressed: () {
setState(() {
counter++;
});
},
),
],
),
),
);
}
}
Widget分类 #
StatelessWidget #
StatelessWidget用于不需要状态变化的UI组件。
dart
class WelcomeCard extends StatelessWidget {
final String title;
final String subtitle;
final IconData icon;
const WelcomeCard({
Key? key,
required this.title,
required this.subtitle,
required this.icon,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
elevation: 4.0,
margin: EdgeInsets.all(16.0),
child: Padding(
padding: EdgeInsets.all(16.0),
child: Row(
children: [
Icon(icon, size: 48, color: Colors.blue),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.headlineSmall,
),
SizedBox(height: 8),
Text(
subtitle,
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
),
],
),
),
);
}
}
class StatelessExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Stateless Widget Example')),
body: Column(
children: [
WelcomeCard(
title: 'Welcome',
subtitle: 'This is a stateless widget example',
icon: Icons.home,
),
WelcomeCard(
title: 'About',
subtitle: 'Stateless widgets never change',
icon: Icons.info,
),
],
),
);
}
}
StatefulWidget #
StatefulWidget用于需要状态变化的UI组件。
dart
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Stateful Widget Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Counter Value:',
style: Theme.of(context).textTheme.titleLarge,
),
Text(
'$_counter',
style: Theme.of(context).textTheme.displayLarge?.copyWith(
color: Colors.blue,
),
),
],
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _incrementCounter,
child: Icon(Icons.add),
heroTag: 'increment',
),
SizedBox(width: 8),
FloatingActionButton(
onPressed: _decrementCounter,
child: Icon(Icons.remove),
heroTag: 'decrement',
),
],
),
);
}
void _incrementCounter() {
setState(() {
_counter++;
});
}
void _decrementCounter() {
setState(() {
if (_counter > 0) _counter--;
});
}
}
基础Widget #
Container #
Container是最常用的布局Widget,提供装饰、填充、边距等功能。
dart
class ContainerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Container Demo')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
// 基础Container
Container(
width: 200,
height: 100,
color: Colors.blue,
child: Center(
child: Text(
'Basic Container',
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(height: 16),
// 带装饰的Container
Container(
width: 250,
height: 120,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.purple, Colors.orange],
),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10,
offset: Offset(0, 5),
),
],
),
child: Center(
child: Text(
'Styled Container',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
),
SizedBox(height: 16),
// 带边距和填充的Container
Container(
margin: EdgeInsets.all(8.0),
padding: EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(12),
),
child: Text(
'Container with padding and margin',
style: TextStyle(color: Colors.white),
),
),
],
),
),
);
}
}
Text Widget #
Text Widget用于显示文本内容。
dart
class TextDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Text Widget Demo')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Basic Text',
style: TextStyle(fontSize: 16),
),
SizedBox(height: 16),
// 样式化文本
Text(
'Styled Text with various properties',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.blue,
fontStyle: FontStyle.italic,
decoration: TextDecoration.underline,
),
),
SizedBox(height: 16),
// 富文本
RichText(
text: TextSpan(
style: TextStyle(color: Colors.black, fontSize: 16),
children: [
TextSpan(text: 'This is '),
TextSpan(
text: 'bold',
style: TextStyle(fontWeight: FontWeight.bold),
),
TextSpan(text: ' and this is '),
TextSpan(
text: 'italic',
style: TextStyle(fontStyle: FontStyle.italic),
),
TextSpan(text: '.'),
],
),
),
SizedBox(height: 16),
// 长文本处理
Text(
'This is a very long text that demonstrates how Flutter handles text overflow. '
'When text is too long to fit in its container, Flutter provides various ways '
'to handle the overflow, such as clipping, fading, or showing ellipsis.',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14),
),
],
),
),
);
}
}
Image Widget #
Image Widget用于显示图像。
dart
class ImageDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Image Widget Demo')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
children: [
// 网络图片
Container(
height: 200,
width: double.infinity,
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.network(
'https://via.placeholder.com/400x200',
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes != null
? loadingProgress.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: null,
),
);
},
errorBuilder: (context, error, stackTrace) {
return Icon(
Icons.error,
size: 50,
color: Colors.red,
);
},
),
),
),
SizedBox(height: 16),
// 本地图片
Image.asset(
'assets/images/sample.jpg', // 需要在pubspec.yaml中声明
width: 200,
height: 150,
fit: BoxFit.cover,
),
SizedBox(height: 16),
// 图片修饰
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage('https://via.placeholder.com/200'),
fit: BoxFit.cover,
),
),
),
],
),
),
),
);
}
}
布局Widget #
Row和Column #
Row用于水平布局,Column用于垂直布局。
dart
class RowColumnDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Row & Column Demo')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
// Row示例
Container(
height: 80,
color: Colors.grey[100],
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 60,
height: 60,
color: Colors.red,
child: Center(child: Text('1', style: TextStyle(color: Colors.white))),
),
Container(
width: 60,
height: 60,
color: Colors.green,
child: Center(child: Text('2', style: TextStyle(color: Colors.white))),
),
Container(
width: 60,
height: 60,
color: Colors.blue,
child: Center(child: Text('3', style: TextStyle(color: Colors.white))),
),
],
),
),
SizedBox(height: 16),
// Column示例
Container(
width: double.infinity,
color: Colors.grey[100],
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: double.infinity,
height: 50,
color: Colors.orange,
child: Center(child: Text('Top')),
),
Container(
width: double.infinity,
height: 50,
color: Colors.pink,
child: Center(child: Text('Middle')),
),
Container(
width: double.infinity,
height: 50,
color: Colors.purple,
child: Center(child: Text('Bottom')),
),
],
),
),
SizedBox(height: 16),
// Expanded示例
Container(
height: 60,
child: Row(
children: [
Container(
width: 60,
color: Colors.grey,
child: Center(child: Text('Fixed')),
),
Expanded(
child: Container(
color: Colors.lightBlue,
child: Center(child: Text('Expanded')),
),
),
Container(
width: 60,
color: Colors.grey,
child: Center(child: Text('Fixed')),
),
],
),
),
],
),
),
);
}
}
Flexible和Expanded #
Flexible和Expanded用于处理可用空间的分配。
dart
class FlexibleExpandedDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flexible & Expanded Demo')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
// Flexible示例
Container(
height: 60,
child: Row(
children: [
Flexible(
flex: 2,
child: Container(
color: Colors.red,
child: Center(child: Text('Flex 2', style: TextStyle(color: Colors.white))),
),
),
Flexible(
flex: 1,
child: Container(
color: Colors.green,
child: Center(child: Text('Flex 1', style: TextStyle(color: Colors.white))),
),
),
Flexible(
flex: 1,
child: Container(
color: Colors.blue,
child: Center(child: Text('Flex 1', style: TextStyle(color: Colors.white))),
),
),
],
),
),
SizedBox(height: 16),
// Expanded示例
Container(
height: 60,
child: Row(
children: [
Container(
width: 50,
color: Colors.grey,
child: Center(child: Text('50')),
),
Expanded(
child: Container(
color: Colors.yellow,
child: Center(child: Text('Expanded')),
),
),
Container(
width: 50,
color: Colors.grey,
child: Center(child: Text('50')),
),
],
),
),
SizedBox(height: 16),
// Nested example
Container(
height: 100,
child: Row(
children: [
Expanded(
flex: 1,
child: Container(
color: Colors.purple,
child: Column(
children: [
Expanded(
child: Container(color: Colors.purple[200], child: Center(child: Text('Nested 1'))),
),
Expanded(
child: Container(color: Colors.purple[400], child: Center(child: Text('Nested 2'))),
),
],
),
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.orange,
child: Center(child: Text('Main Expanded')),
),
),
],
),
),
],
),
),
);
}
}
ListView #
ListView用于显示可滚动的列表。
dart
class ListViewDemo extends StatelessWidget {
final List<String> items = List.generate(50, (index) => 'Item ${index + 1}');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('ListView Demo')),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Card(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: ListTile(
leading: CircleAvatar(child: Text('${index + 1}')),
title: Text(items[index]),
subtitle: Text('Description for ${items[index]}'),
trailing: Icon(Icons.arrow_forward_ios),
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Tapped ${items[index]}')),
);
},
),
);
},
),
);
}
}
// 水平ListView
class HorizontalListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 120,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: 20,
separatorBuilder: (context, index) => SizedBox(width: 8),
itemBuilder: (context, index) {
return Container(
width: 100,
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: BorderRadius.circular(8),
),
child: Center(child: Text('Item $index')),
);
},
),
);
}
}
GridView #
GridView用于显示网格布局。
dart
class GridViewDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('GridView Demo')),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // 每行2个项目
crossAxisSpacing: 8,
mainAxisSpacing: 8,
childAspectRatio: 1.2, // 高宽比
),
itemCount: 20,
itemBuilder: (context, index) {
return Card(
child: GridTile(
header: Container(
color: Colors.blue,
child: Center(
child: Text(
'Header $index',
style: TextStyle(color: Colors.white),
),
),
),
child: Center(child: Text('Item $index')),
footer: Container(
color: Colors.grey,
child: Center(
child: Text(
'Footer',
style: TextStyle(color: Colors.white),
),
),
),
),
);
},
),
);
}
}
// 网格视图的其他样式
class GridViewVariants extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('GridView Variants'),
bottom: TabBar(
tabs: [
Tab(text: 'Fixed Count'),
Tab(text: 'Max Cross Size'),
Tab(text: 'Builder'),
],
),
),
body: TabBarView(
children: [
// Fixed cross axis count
GridView.count(
crossAxisCount: 3,
children: List.generate(12, (index) {
return Card(
child: Center(child: Text('Item $index')),
);
}),
),
// Max cross axis extent
GridView.extent(
maxCrossAxisExtent: 150,
childAspectRatio: 1,
children: List.generate(15, (index) {
return Card(
color: Colors.primaries[index % Colors.primaries.length],
child: Center(child: Text('Item $index')),
);
}),
),
// Builder
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 1,
),
itemCount: 25,
itemBuilder: (context, index) {
return Card(
child: Center(child: Text('Item $index')),
);
},
),
],
),
),
);
}
}
手势检测Widget #
GestureDetector #
GestureDetector用于检测各种手勢。
dart
class GestureDemo extends StatefulWidget {
@override
_GestureDemoState createState() => _GestureDemoState();
}
class _GestureDemoState extends State<GestureDemo> {
String _gestureInfo = 'Tap, double tap, or long press the box below';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Gesture Detection Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 200,
height: 200,
child: GestureDetector(
onTap: () {
setState(() {
_gestureInfo = 'Single tap detected!';
});
},
onDoubleTap: () {
setState(() {
_gestureInfo = 'Double tap detected!';
});
},
onLongPress: () {
setState(() {
_gestureInfo = 'Long press detected!';
});
},
onPanUpdate: (details) {
// 拖拽移动
setState(() {
_gestureInfo = 'Dragging...';
});
},
onScaleUpdate: (details) {
// 缩放
setState(() {
_gestureInfo = 'Scaling...';
});
},
child: Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(12),
),
child: Center(
child: Text(
'Gesture Area',
style: TextStyle(color: Colors.white),
),
),
),
),
),
SizedBox(height: 32),
Text(
_gestureInfo,
style: TextStyle(fontSize: 16),
textAlign: TextAlign.center,
),
],
),
),
);
}
}
表单Widget #
TextField #
TextField用于文本输入。
dart
class FormDemo extends StatefulWidget {
@override
_FormDemoState createState() => _FormDemoState();
}
class _FormDemoState extends State<FormDemo> {
final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
String _formData = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Form Demo')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: ListView(
children: [
TextFormField(
controller: _nameController,
decoration: InputDecoration(
labelText: 'Name',
hintText: 'Enter your name',
prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your name';
}
if (value.length < 2) {
return 'Name should be at least 2 characters';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
controller: _emailController,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'Enter your email',
prefixIcon: Icon(Icons.email),
border: OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
return 'Please enter a valid email';
}
return null;
},
),
SizedBox(height: 16),
TextFormField(
controller: _passwordController,
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Enter your password',
prefixIcon: Icon(Icons.lock),
border: OutlineInputBorder(),
),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
if (value.length < 6) {
return 'Password should be at least 6 characters';
}
return null;
},
),
SizedBox(height: 24),
ElevatedButton(
onPressed: _submitForm,
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 16),
),
child: Text('Submit', style: TextStyle(fontSize: 16)),
),
SizedBox(height: 24),
Text(
_formData,
style: TextStyle(fontSize: 16),
),
],
),
),
),
);
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
setState(() {
_formData = 'Name: ${_nameController.text}\n'
'Email: ${_emailController.text}\n'
'Password: ${_passwordController.text}';
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Form submitted successfully!')),
);
}
}
@override
void dispose() {
_nameController.dispose();
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
}
自定义Widget #
组合现有Widget #
dart
// 自定义输入框Widget
class CustomInputField extends StatelessWidget {
final String label;
final String hint;
final IconData icon;
final TextEditingController controller;
final String? Function(String?)? validator;
final bool obscureText;
const CustomInputField({
Key? key,
required this.label,
required this.hint,
required this.icon,
required this.controller,
this.validator,
this.obscureText = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
controller: controller,
decoration: InputDecoration(
labelText: label,
hintText: hint,
prefixIcon: Icon(icon),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.blue, width: 2),
),
),
obscureText: obscureText,
validator: validator,
);
}
}
// 自定义按钮Widget
class CustomButton extends StatelessWidget {
final String text;
final VoidCallback onPressed;
final Color color;
final double height;
const CustomButton({
Key? key,
required this.text,
required this.onPressed,
this.color = Colors.blue,
this.height = 50,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: height,
width: double.infinity,
child: ElevatedButton(
onPressed: onPressed,
style: ElevatedButton.styleFrom(
backgroundColor: color,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
text,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
);
}
}
// 使用自定义Widget的表单
class CustomFormDemo extends StatefulWidget {
@override
_CustomFormDemoState createState() => _CustomFormDemoState();
}
class _CustomFormDemoState extends State<CustomFormDemo> {
final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Custom Widget Form')),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
CustomInputField(
label: 'Full Name',
hint: 'Enter your full name',
icon: Icons.person,
controller: _nameController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Name is required';
}
return null;
},
),
SizedBox(height: 16),
CustomInputField(
label: 'Email',
hint: 'Enter your email',
icon: Icons.email,
controller: _emailController,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
return 'Invalid email format';
}
return null;
},
),
SizedBox(height: 16),
CustomInputField(
label: 'Password',
hint: 'Enter your password',
icon: Icons.lock,
controller: _passwordController,
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password is required';
}
if (value.length < 6) {
return 'Password must be at least 6 characters';
}
return null;
},
),
SizedBox(height: 32),
CustomButton(
text: 'Sign Up',
onPressed: () {
if (_formKey.currentState!.validate()) {
print('Form is valid');
// 处理表单提交
}
},
),
],
),
),
),
);
}
@override
void dispose() {
_nameController.dispose();
_emailController.dispose();
_passwordController.dispose();
super.dispose();
}
}
Widget生命周期 #
dart
class LifecycleDemo extends StatefulWidget {
@override
_LifecycleDemoState createState() => _LifecycleDemoState();
}
class _LifecycleDemoState extends State<LifecycleDemo> {
int counter = 0;
@override
void initState() {
super.initState();
print('initState called');
// 初始化工作
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('didChangeDependencies called');
// InheritedWidget变化时调用
}
@override
void didUpdateWidget(covariant LifecycleDemo oldWidget) {
super.didUpdateWidget(oldWidget);
print('didUpdateWidget called');
// 父Widget重建时调用
}
@override
void deactivate() {
super.deactivate();
print('deactivate called');
// Widget从树中移除时调用(可能重新插入)
}
@override
void dispose() {
print('dispose called');
// 清理工作
super.dispose();
}
@override
Widget build(BuildContext context) {
print('build called');
return Scaffold(
appBar: AppBar(title: Text('Lifecycle Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter: $counter'),
ElevatedButton(
onPressed: () {
setState(() {
counter++;
});
},
child: Text('Increment'),
),
],
),
),
);
}
}
总结 #
Flutter的Widget系统提供了丰富的UI构建组件,通过组合不同的Widget可以创建复杂的用户界面。理解Widget的分类、生命周期和使用方法是Flutter开发的核心技能。合理使用StatelessWidget和StatefulWidget,结合布局Widget和交互Widget,可以构建出功能丰富、用户体验良好的应用程序。