Flutter 自定义组件
Flutter 的自定义组件实质为 Dart 类,使用时需要通过实例化创建组件的实例对象
定义
静态组件 ( StatelessWidget )
静态组件展示的内容不依赖响应变化的状态数据,常用于创建不可变对象来展示静态内容
定义时必需继承内置组件类StatelessWidget
组件内可定义状态属性,但是不会随用户交互而变化也不会因为变化而重新绘制展示内容
dart
class 自定义组件类名 extends StatelessWidget {
const 自定义组件类名({super.key});
@override
Widget build(BuildContext context) {
return 其他组件实例;
}
}
const 自定义组件实例 = const 自定义组件类名();
例子:
dart
import 'package:flutter/material.dart';
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Text(
'Hello World',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
);
}
}
void main() {
runApp(const MyWidget());
}
动态组件 ( StatefulWidget )
动态组件展示的内容依赖响应变化的状态数据
定义时必需继承内置组件类StatefulWidget
组件内可定义状态属性,因为户交互变化时会重新绘制展示内容
dart
class 自定义组件类名 extends StatefulWidget {
自定义组件类名({super.key});
@override
State<自定义组件类名> createState() => _自定义组件类名State类();
}
class _自定义组件类名State类 extends State<自定义组件类名> {
数据类型 _私有状态1 = 初始值;
数据类型 _私有状态2 = 初始值;
返回值类型 _私有方法() {
setState(() => _私有状态1的新值);
setState(() => _私有状态2的新值);
}
返回值类型 _私有方法() {
setState(() {
_私有状态1 = 新值;
_私有状态1 = 新值;
});
}
@override
Widget build(BuildContext context) {
return 其他组件实例;
}
}
var 自定义组件实例 = 自定义组件类名();
例子:
dart
import 'package:flutter/material.dart';
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _count = 0;
String _message = "";
void _increaseCount() {
setState(() => _count++);
}
void _getMessage() {
setState(() => _message = _count.toString() * 10);
}
void _clearAll() {
setState(() {
_count = 0;
_message = "";
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(_message),
Text(_count.toString()),
Row(children: [
ElevatedButton(
onPressed: _increaseCount,
child: Text("+1"),
),
ElevatedButton(
onPressed: _getMessage,
child: Text("get Message", overflow: TextOverflow.ellipsis),
),
ElevatedButton(
onPressed: _clearAll,
child: Text("clear all"),
)
])
],
);
}
}
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: const MyApp(),
),
),
);
}
数据传递
基于 Dart 类实现组件间数据传递:
- 实例化组件时传递参数给组件类
- 组件类内部通过构造函数接收参数并更新自身的实例属性
dart
class 自定义组件类 extends StatelessWidget {
final 数据类型 实例属性;
final 数据类型 实例属性;
自定义组件类(this.实例属性, {super.key, this.实例属性});
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("$实例属性"),
Text("$实例属性"),
]
);
}
}
var 自定义组件实例 = 自定义组件类(参数, 属性: 参数);
dart
class 自定义组件类 extends StatefulWidget {
final 数据类型 实例属性;
final 数据类型 实例属性;
自定义组件类(this.实例属性, {super.key, this.实例属性});
@override
State<自定义组件类名> createState() => _自定义组件类State类();
}
class _自定义组件类State类 extends State<自定义组件类名> {
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("$widget.实例属性"),
Text("$widget.实例属性"),
]
);
}
}
例子:
dart
import 'package:flutter/material.dart';
class CustomButton extends StatelessWidget {
/** 按钮文本 */
final String text;
/** 按钮点击事件 */
final void Function() onPress;
/** 按钮是否充填父组件 */
final bool? isExpanded;
CustomButton(
this.text, {
super.key,
required this.onPress,
this.isExpanded,
});
@override
Widget build(BuildContext context) {
return Expanded(
flex: this.isExpanded == true ? 1 : 0,
child: Container(
child: ElevatedButton(
onPressed: this.onPress,
child: Text(this.text),
),
),
);
}
}
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: Row(
children: [
CustomButton("xxxx", onPress: () => print("xxxx")),
CustomButton("yyyy", onPress: () => print("yyyy")),
CustomButton("zzz", onPress: () => print("zzz"), isExpanded: true),
],
),
),
),
);
}
dart
import 'package:flutter/material.dart';
class CustomButton extends StatefulWidget {
/** 按钮文本 */
final String text;
/** 按钮点击事件 */
final void Function() onPress;
/** 按钮是否充填父组件 */
final bool? isExpanded;
CustomButton(
this.text, {
super.key,
required this.onPress,
this.isExpanded,
});
@override
State<CustomButton> createState() => _CustomButtonState();
}
class _CustomButtonState extends State<CustomButton> {
@override
Widget build(BuildContext context) {
return Expanded(
flex: widget.isExpanded == true ? 1 : 0,
child: Container(
child: ElevatedButton(
onPressed: widget.onPress,
child: Text(widget.text),
),
),
);
}
}
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: Row(
children: [
CustomButton("xxxx", onPress: () => print("xxxx")),
CustomButton("yyyy", onPress: () => print("yyyy")),
CustomButton("zzz", onPress: () => print("zzz"), isExpanded: true),
],
),
),
),
);
}
生命周期
只有动态组件组件类 StatefulWidget 内部才有生命周期
StatefulWidget State Class
┌─────────────────────┐ ┌─────────────────────────────────────────────────┐
│ ┌───────────────┐ │ │ ┌─────────────────────────┐ │
│ │ constructor │ │ │ │ initState() │ │
│ └───────┼───────┘ │ │ └────────────┼────────────┘ │
│ ┌───────▼───────┐ │ │ ┌────────────▼────────────┐ │
│ │ createState() │ ─┼───▶│ │ didChangeDependencies() │ │
│ └───────────────┘ │ │ └────────────┼────────────┘ │
└─────────────────────┘ │ │ ┌───────────────────┐ │
│ │◀─────────┼ didUpdateWidget() │ │
│ ┌────────▼────────┐ └─────────▲─────────┘ │
│ │ build() │ │ │
│ └────────┼────────┘ ┌──────┼──────┐ │
│ ├────────────▶│ setState │ │
│ │ └─────────────┘ │
│ │ │
│ │ ┌───────────────────┐ │
│ │ │ dispose() │ │
│ ▼ └───────────────────┘ │
└─────────────────────────────────────────────────┘
dart
class 自定义组件类名 extends StatefulWidget {
const 自定义组件类名({super.key}) : super(key: key);
@override
State<自定义组件类名> createState() => _自定义组件类名State类();
}
class _自定义组件类名State类 extends State<自定义组件类名> {、
@override
void initState() {
super.initState();
// 组件初始化时执行 ...
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// 组件依赖发生变化时执行 ...
}
@override
void didUpdateWidget() {
super.didUpdateWidget();
// 组件更新时执行 ...
}
@override
void dispose() {
super.dispose();
// 组件销毁时执行 ...
}
@override
Widget build(BuildContext context) {
return 要展示到界面的组件实例;
}
}