前言
flutter的状态管理有provider,riverpod,getx等方案,但是在开发中,存在着大量父子组件通信并不需要进行状态管理的情况。这里介绍下组件传值常用情况
1. 父传子
父组件通过传递参数,将值给子组件
//---------------------------- ParentWidget ----------------------------
class ParentWidget extends StatefulWidget {
const ParentWidget({super.key});
@override
State<ParentWidget> createState() => _ParentWidgetCState();
}
class _ParentWidgetCState extends State<ParentWidget> {
bool _active = false; //定义状态
void _handleTapboxChanged() {
setState(() {
_active = !_active;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
InkWell(
child: const Text('点击'),
onTap: () {
_handleTapboxChanged();
},
),
Tapbox(active: _active),//传递状态
],
),
);
}
}
//----------------------------- Tapbox ------------------------------
class Tapbox extends StatefulWidget {
final bool active;
const Tapbox({super.key, required this.active});
@override
State<Tapbox> createState() => _TapboxCState();
}
class _TapboxCState extends State<Tapbox> {
@override
Widget build(BuildContext context) {
return Text(
widget.active ? 'Active' : 'Inactive',
);
}
}
2. 子传父
父组件定义状态和改变状态的方法,并传递给子组件;子组件通过给方法传值来改变父组件的状态
//---------------------------- ParentWidget ----------------------------
class ParentWidget extends StatefulWidget {
const ParentWidget({super.key});
@override
State<ParentWidget> createState() => _ParentWidgetCState();
}
class _ParentWidgetCState extends State<ParentWidget> {
bool _active = false; //定义状态
void _handleTapboxChanged(bool newValue) {
//定义改变状态的方法
setState(() {
_active = newValue;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Tapbox( //传递状态和改变状态的方法
active: _active,
onChanged: _handleTapboxChanged,
),
);
}
}
//----------------------------- Tapbox ------------------------------
class Tapbox extends StatefulWidget {
const Tapbox({super.key, required this.active, required this.onChanged});
final bool active;
final void Function(bool newValue) onChanged;
@override
State<Tapbox> createState() => _TapboxCState();
}
class _TapboxCState extends State<Tapbox> {
void _handleTap() {
widget.onChanged(!widget.active); //给方法传值
}
@override
Widget build(BuildContext context) {
return InkWell(
onTap: _handleTap,
child: Text(
widget.active ? 'Active' : 'Inactive',
),
);
}
}
3. 父调用子
借助GlobalKey获取到子组件
//---------------------------- ParentWidget ----------------------------
GlobalKey<TapboxCState> childKey = GlobalKey(); //1. 创建 globalKey
class ParentWidget extends StatefulWidget {
const ParentWidget({super.key});
@override
State<ParentWidget> createState() => _ParentWidgetCState();
}
class _ParentWidgetCState extends State<ParentWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Tapbox(
key: childKey, // 2. 给子组件传递一个 globalKey
),
InkWell(
onTap: () {
// 3. 通过 globalKey 的 currentState 获取方法
childKey.currentState
?.handleTap();
},
child: const Text('点击'),
)
],
),
);
}
}
//----------------------------- Tapbox ------------------------------
class Tapbox extends StatefulWidget {
const Tapbox({super.key});
@override
State<Tapbox> createState() => TapboxCState();
}
class TapboxCState extends State<Tapbox> {
void handleTap() {
print('被调用');
}
@override
Widget build(BuildContext context) {
return const Text(
'子组件',
);
}
}
4. 上下文传值(InheritedWidget)
- 新建persionShareDataWidget.dart
import 'package:flutter/material.dart';
class PersionShareDataWidget extends InheritedWidget {
const PersionShareDataWidget({
super.key,
required this.data,
required super.child,
});
final Person data; //需要在子树中共享的数据
//提供一个 “of” 静态方法来获取其对象
static PersionShareDataWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<PersionShareDataWidget>();
}
//当data发生变化时,是否通知子树中依赖data的Widget重新build
@override
bool updateShouldNotify(PersionShareDataWidget oldWidget) {
return oldWidget.data != data;
}
}
class Person{
String name;
int age;
Person({required this.name, required this.age});
}
- 使用
import 'package:flutter/material.dart';
import 'persionShareDataWidget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const GrandFather(),
);
}
}
class GrandFather extends StatefulWidget {
const GrandFather({super.key});
@override
State<GrandFather> createState() => _GrandFatherState();
}
class _GrandFatherState extends State<GrandFather> {
Person person = Person(name: '张三', age: 18);
@override
Widget build(BuildContext context) {
return Scaffold(
body: PersionShareDataWidget(
data: person,
child: Column(
children: [
const Text('祖先组件'),
const Child(),
ElevatedButton(
child: const Text("Increment"),
//更新数据
onPressed: () => setState(() {
person = Person(name: '李四', age: 19);
}),
)
],
)),
);
}
}
class Child extends StatefulWidget {
const Child({super.key});
@override
State<Child> createState() => _ChildState();
}
class _ChildState extends State<Child> {
@override
Widget build(BuildContext context) {
Person person = PersionShareDataWidget.of(context)!.data; //获取到上下文中的值
return Text('${person.name.toString()}:${person.age.toString()}');
}
}
结尾
import 'package:flutter/material.dart';
class PersionShareDataWidget extends InheritedWidget {
const PersionShareDataWidget({
super.key,
required this.data,
required super.child,
});
final Person data; //需要在子树中共享的数据
//提供一个 “of” 静态方法来获取其对象
static PersionShareDataWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<PersionShareDataWidget>();
}
//当data发生变化时,是否通知子树中依赖data的Widget重新build
@override
bool updateShouldNotify(PersionShareDataWidget oldWidget) {
return oldWidget.data != data;
}
}
class Person{
String name;
int age;
Person({required this.name, required this.age});
}
import 'package:flutter/material.dart';
import 'persionShareDataWidget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const GrandFather(),
);
}
}
class GrandFather extends StatefulWidget {
const GrandFather({super.key});
@override
State<GrandFather> createState() => _GrandFatherState();
}
class _GrandFatherState extends State<GrandFather> {
Person person = Person(name: '张三', age: 18);
@override
Widget build(BuildContext context) {
return Scaffold(
body: PersionShareDataWidget(
data: person,
child: Column(
children: [
const Text('祖先组件'),
const Child(),
ElevatedButton(
child: const Text("Increment"),
//更新数据
onPressed: () => setState(() {
person = Person(name: '李四', age: 19);
}),
)
],
)),
);
}
}
class Child extends StatefulWidget {
const Child({super.key});
@override
State<Child> createState() => _ChildState();
}
class _ChildState extends State<Child> {
@override
Widget build(BuildContext context) {
Person person = PersionShareDataWidget.of(context)!.data; //获取到上下文中的值
return Text('${person.name.toString()}:${person.age.toString()}');
}
}
如果有不对或者需要补充的,欢迎在评论区留言