logo
GitHub

Flutter Widget 基础

什么是 Widget?

Widget 是 Flutter 中构建用户界面的基本单位。在 Flutter 中,一切皆为 Widget,从一个简单的按钮到整个应用程序,都是由 Widget 组成的。Widget 描述了在当前配置和状态下视图应该呈现的样子。

Widget 的特点

  • 不可变性:Widget 是不可变的,每次更新都会创建新的 Widget 实例
  • 组合性:复杂的 Widget 可以由简单的 Widget 组合而成
  • 层次结构:Widget 以树形结构组织,形成 Widget 树

Widget 的分类

1. StatelessWidget(无状态组件)

适用于界面内容固定,不需要动态更新的场景。

class WelcomeMessage extends StatelessWidget {
final String name;
const WelcomeMessage({Key? key, required this.name}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text('Welcome, $name!');
}
}

2. StatefulWidget(有状态组件)

适用于需要动态更新界面内容的场景。

class Counter extends StatefulWidget {
const Counter({Key? key}) : super(key: key);
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
void _increment() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(
onPressed: _increment,
child: const Text('Increment'),
),
],
);
}
}

常用的基础 Widget

1. 布局 Widget

// 线性布局
Row( // 水平排列
children: [
Icon(Icons.star),
Text('Rating: 4.5'),
],
)
Column( // 垂直排列
children: [
Text('Title'),
Text('Subtitle'),
],
)
// 弹性布局
Flex(
direction: Axis.horizontal,
children: [
Expanded(
flex: 2, // 占用 2/3 空间
child: Container(color: Colors.red),
),
Expanded(
flex: 1, // 占用 1/3 空间
child: Container(color: Colors.blue),
),
],
)
// 堆叠布局
Stack(
children: [
Image.asset('background.png'),
Positioned(
bottom: 10,
right: 10,
child: Text('Overlay Text'),
),
],
)

2. 容器 Widget

// 基础容器
Container(
margin: EdgeInsets.all(8.0),
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Text('Hello Flutter!'),
)
// 卡片容器
Card(
child: ListTile(
leading: Icon(Icons.album),
title: Text('Album Title'),
subtitle: Text('Artist Name'),
trailing: Icon(Icons.more_vert),
),
)

3. 基础组件

// 文本
Text(
'Hello Flutter!',
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
)
// 图片
Image.network(
'https://example.com/image.jpg',
width: 200,
height: 200,
fit: BoxFit.cover,
)
// 按钮
ElevatedButton(
onPressed: () {
print('Button pressed!');
},
child: Text('Click Me'),
)
TextButton(
onPressed: () {
print('Text button pressed!');
},
child: Text('Text Button'),
)
IconButton(
onPressed: () {
print('Icon button pressed!');
},
icon: Icon(Icons.favorite),
)

Widget 生命周期

对于 StatefulWidget,其生命周期包括以下阶段:

  1. createState():创建 State 对象
  2. initState():State 对象初始化
  3. didChangeDependencies():依赖变化时调用
  4. build():构建 Widget
  5. didUpdateWidget():Widget 配置更新时调用
  6. setState():状态更新时调用
  7. dispose():Widget 销毁时调用
class LifecycleWidget extends StatefulWidget {
const LifecycleWidget({Key? key}) : super(key: key);
@override
_LifecycleWidgetState createState() => _LifecycleWidgetState();
}
class _LifecycleWidgetState extends State<LifecycleWidget> {
@override
void initState() {
super.initState();
print('1. initState called');
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print('2. didChangeDependencies called');
}
@override
Widget build(BuildContext context) {
print('3. build called');
return Container(
child: Text('Lifecycle Demo'),
);
}
@override
void didUpdateWidget(covariant LifecycleWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print('4. didUpdateWidget called');
}
@override
void dispose() {
print('5. dispose called');
super.dispose();
}
}

实践:创建一个简单的计数器应用

结合所学的 Widget 知识,创建一个完整的计数器应用:

import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}

下一步

掌握了 Widget 的基础知识后,我们将在下一章学习 Flutter 的状态管理,包括 setState、Provider、Riverpod 等不同的状态管理方案。