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,其生命周期包括以下阶段:
- createState():创建 State 对象
- initState():State 对象初始化
- didChangeDependencies():依赖变化时调用
- build():构建 Widget
- didUpdateWidget():Widget 配置更新时调用
- setState():状态更新时调用
- 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 等不同的状态管理方案。