通信实现方式
回调通信
需求“点击子组件,修改父组件的背景颜色与子组件背景颜色一致”
使用场景:一般用于子组件对父组件传值。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
///使用场景:一般用于子组件对父组件传值。
class ParentWidget extends StatefulWidget {
final String? title;
ParentWidget({Key? key,this.title}):super(key: key);
@override
State<StatefulWidget> createState() {
return ParentWidgetState();
}
}
class ParentWidgetState extends State<ParentWidget>{
Color containerBg = Colors.orange;
//回调函数
void changeBackgroundColor(Color newColor){
setState(() {
containerBg = newColor;//修改状态
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title??""),
),
body: new Center(
child: new GestureDetector(
onTap: (){
},
child: new Container(
width: 300,
height: 300,
color: containerBg,
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
childrenA(childrenABallback: changeBackgroundColor,),
childrenB(childrenBBallback: changeBackgroundColor,),
],
),
),
),
),
);
}
}
///自组件 A
class childrenA extends StatelessWidget {
final ValueChanged<Color>? childrenABallback;
childrenA({Key? key,this.childrenABallback});
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: (){
childrenABallback!(Colors.green);
},
child: new Container(
width: 80,
height: 80,
color: Colors.green,
child: new Text("ChildrenA"),
),
);
}
}
///自组件 A
class childrenB extends StatelessWidget {
final ValueChanged<Color>? childrenBBallback;
childrenB({Key? key,this.childrenBBallback});
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: (){
childrenBBallback!(Colors.red);
},
child: new Container(
width: 80,
height: 80,
color: Colors.red,
child: new Text("ChildrenB"),
),
);
}
}
2941690359496_.pic.jpg
InheritedWidget 数据共享
场景:业务开发中经常会碰到这样的情况,多个Widget需要同步同一份全局数据,比如点赞数、评论数、夜间模式等等。
使用场景 一般用于父组件对子组件的跨组件传值。
//模型数据
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
///一般用于父组件对子组件的跨组件传值。
class InheritedTestModel {
final int count;
const InheritedTestModel(this.count);
}
//哨所(自定义InheritedWidget类)
class InheritedContext extends InheritedWidget {
//变量
final InheritedTestModel inheritedTestModel;
final Function() increment;
final Function() reduce;
InheritedContext({Key? key,
required this.inheritedTestModel,
required this.increment,
required this.reduce,
required Widget child,
}) : super(key:key,child: child);
//定义一个便捷方法,方便子树中的widget获取共享数据
static InheritedContext? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<InheritedContext>();
}
//是否重建取决于Widget组件是否相同
@override
bool updateShouldNotify(InheritedContext oldWidget) {
return inheritedTestModel != oldWidget.inheritedTestModel;
}
}
class TestWidgetA extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("TestWidgetA build");
var of = InheritedContext.of(context);
return new Padding(
padding: const EdgeInsets.only(left: 10,top: 10,right: 10),
child: new RaisedButton(
textColor: Colors.black,
child: Text("+"),
onPressed: of?.increment
),
);
}
}
class TestWidgetB extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("TestWidgetB build");
var of = InheritedContext.of(context);
return new Padding(
padding: const EdgeInsets.only(left: 10,top: 10,right: 10),
child: new RaisedButton(
textColor: Colors.black,
child: Text("-"),
onPressed: of?.reduce
),
);
}
}
class TestWidgetC extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("TestWidgetC build");
var of = InheritedContext.of(context);
var model = of?.inheritedTestModel;
return new Padding(
padding: const EdgeInsets.only(left: 10,top: 10,right: 10),
child: new RaisedButton(
textColor: Colors.black,
child: Text('${model?.count}'),
onPressed: (){
}
),
);
}
}
class InheritedWidgetTestContainer extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new InheritedWidgetTestContainerState();
}
}
class InheritedWidgetTestContainerState extends State<InheritedWidgetTestContainer> {
InheritedTestModel? _inheritedTestModel;
_initData(){
_inheritedTestModel = new InheritedTestModel(0);
}
@override
void initState() {
_initData();
super.initState();
}
_incrementCount(){
setState(() {
_inheritedTestModel = new InheritedTestModel(1 + (_inheritedTestModel?.count??0));
});
}
_reduceCount(){
setState(() {
_inheritedTestModel = new InheritedTestModel((_inheritedTestModel?.count??0) - 1);
});
}
@override
Widget build(BuildContext context) {
return InheritedContext(
inheritedTestModel: _inheritedTestModel!,
increment: _incrementCount,
reduce: _reduceCount,
child: Scaffold(
appBar: AppBar(
title: Text('inheritedWidgetTest'),
),
body: new Center(
child: Column(
children: [
TestWidgetA(),
TestWidgetB(),
TestWidgetC()
],
),
),
));
}
}
2951690359496_.pic.jpg
Global Key通信
GlobalKey能够跨Widget访问状态。
需求“点击A子组件,修改B子组件的背景颜色为指定的‘蓝色”
使用场景:一般用于跨组件访问状态
//父组件
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
///一般用于跨组件访问状态
class ParentGolablWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new ParentGolablWidgetState();
}
}
GlobalKey<SubWidgetAState> subAkey = GlobalKey();
GlobalKey<SubWidgetBState> subBkey = GlobalKey();
class ParentGolablWidgetState extends State<ParentGolablWidget>{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('组件化'),
),
body: Center(
child: Container(
color: Colors.grey,
width: 200,
height: 200,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SubWidgetA(key: subAkey),
SubWidgetB(key: subBkey),
],
),
),
),
);
}
}
class SubWidgetA extends StatefulWidget{
SubWidgetA({Key? key}):super(key: key);
@override
State<StatefulWidget> createState() {
return SubWidgetAState();
}
}
class SubWidgetAState extends State<SubWidgetA>{
Color _backgroundColors = Colors.red;//红色
void updateBackGroundColors(Color colos){
setState(() {
_backgroundColors = colos;
});
}
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: (){
subBkey.currentState?.updateBackGroundColors(Colors.blue);
setState(() {
_backgroundColors = Colors.red;
});
},
child: new Container(
width: 80,
height: 80,
color: _backgroundColors,
alignment: Alignment.center,
child: Text('subWidgetA'),
),
);
}
}
//子组件B
class SubWidgetB extends StatefulWidget {
SubWidgetB({Key? key}):super(key:key);
@override
State<StatefulWidget> createState() {
return new SubWidgetBState();
}
}
class SubWidgetBState extends State<SubWidgetB>{
Color _backgroundColors = Colors.green;//红色
void updateBackGroundColors(Color colos){
setState(() {
_backgroundColors = colos;
});
}
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: (){
subAkey.currentState?.updateBackGroundColors(Colors.blue);
setState(() {
_backgroundColors = Colors.green;
});
},
child: new Container(
width: 80,
height: 80,
color: _backgroundColors,
alignment: Alignment.center,
child: Text('subWidgetB'),
),
);
}
}
2961690359497_.pic.jpg
ValueNotifier通信
ValueNotifier是一个包含单个值的变更通知器,当它的值改变的时候,会通知它的监听
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ValueNotifierData extends ValueNotifier<String>{
ValueNotifierData(super.value);
}
class _WidgetOne extends StatefulWidget {
ValueNotifierData? data;
_WidgetOne({this.data});
@override
State<StatefulWidget> createState() {
return _WidgetOneState();
}
}
class _WidgetOneState extends State<_WidgetOne>{
String? info = null;
@override
void initState() {
super.initState();
widget.data?.addListener(_handleValueChange);
info = 'Initial message: ${widget.data?.value}';
}
@override
void dispose() {
widget.data?.removeListener(_handleValueChange);
super.dispose();
}
void _handleValueChange(){
setState(() {
info = 'Message changed to: ${widget.data?.value}' ;
});
}
@override
Widget build(BuildContext context) {
print("_WidgetOneState build()");
return Container(
child: Center(
child: Text(info??''),
),
);
}
}
class ParentValueNotifierCommunication extends StatelessWidget {
@override
Widget build(BuildContext context) {
ValueNotifierData vd = ValueNotifierData('Hello World');
return Scaffold(
appBar: AppBar(title: Text('Value Notifier Communication'),),
body: _WidgetOne(data: vd,),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.refresh),
onPressed: (){
vd.value = 'Yes';
},
),
);
}
2971690359498_.pic.jpg
第三方插件
event_bus来实现传值
引入插件
import 'package:event_bus/event_bus.dart';
新建消息监测类
import 'package:event_bus/event_bus.dart';
EventBus eventBus = new EventBus();
class TransEvent{
String text;
TransEvent(this.text);
}
监测类变化
eventBus.on<TransEvent>().listen((TransEvent data) => show(data.text));
void show(String val) {
setState(() {
data = val;
});
}
触发消息变化
eventBus.fire(new TransEvent('$inputText'));
网友评论