Flutter如何优雅的使用typedef回调方法
作者简介:Flutter小菜鸡,5年经验移动端开发工程师,努力成为Flutter架构的小菜鸡,现就职于某丰某大数据产品开发处,担任移动端搬砖码农,专注于移动端数据可视化研究,目前没有任何可以拿出来说的成绩【手动狗头】
木本水源篇
旨在简单介绍问题的来源,或技一项技术的背景
在移动开发中,都避免不了回调方法callBack()
,在Flutter编程中也不例外,会用到回调方法,且最开始dart的语法糖把本菜鸡搞得晕头转向,今天就探究一下,callBack()
在Flutter的几种实现形式和原理。
不求甚解篇
旨在快速针对问题,给出解决方案,和实现步骤
废话不多说,直接进入正题,首先在心中默念一句:Flutter万物皆组件,dart万物皆对象。默念完毕之后开始,介绍dart第一种回调方式typedef:
typedef
使用姿势:
首先typedef
是一个关键字或修饰符,因为dart一切皆对象,方法也可理解为对象,所以typedef
也可理解为对象的修饰符,具体意思为: 使用typedef 定义一个函数(或匿名函数),可以使用此函数作为其他函数的参数或返回值
所以这里本菜鸡写了个小demo来使用一下把函数当做参数传递。例子很简单,对法外狂徒张三做一个性别和年龄的调查。
import 'package:flutter/material.dart';
class CallBackHomePage extends StatefulWidget {
@override
_CallBackHomePageState createState() => _CallBackHomePageState();
}
class _CallBackHomePageState extends State<CallBackHomePage> {
String sexStr = '';
int ageInt;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('回调方法demo'),
),
body: Column(
children: [
Container(
child: Text('张三的性别是:$sexStr'),
),
Container(
child: Text(ageInt == null ? '张三的年龄是:' : '张三的年龄是:$ageInt'),
),
BottomView('张三', (sex) {
setState(() {
sexStr = sex;
});
},
(age) => setState(() {
ageInt = age;
}))
],
),
);
}
}
typedef SexFunc = void Function(String sex);
typedef AgeFunc(int age);
class BottomView extends StatelessWidget {
final SexFunc sexCallBack;
final AgeFunc ageCallBack;
BottomView(String name, this.sexCallBack, this.ageCallBack);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(
onPressed: () {
sexCallBack('男');
},
child: Text('调查性别'),
),
RaisedButton(
onPressed: () {
ageCallBack(23);
},
child: Text('调查年龄'),
),
],
),
);
}
}
其中可以看到这两行:
typedef SexFunc = void Function(String sex);
typedef AgeFunc(int age);
其实这是dart的语法糖,SexFuc方法的缩写就是下面的AgeFunc的写法,同样在回调传参的地方也是一个语法糖,如下
BottomView('张三',
(sex) {
setState(() {
sexStr = sex;
});
},
//等价于上面的写法
(age) => setState(() {
ageInt = age;
})
)
两种方式都可以,跟随自己的喜好选择即可。
VoidCallback、ValueChanged
在这里本菜鸡也写了一下所谓的类似OC中的block方法的回调方式。
class CenterView extends StatelessWidget {
VoidCallback sexCallBack;
ValueSetter<int> ageCallBack;
CenterView({Key key, this.sexCallBack, this.ageCallBack}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
RaisedButton(
onPressed: () {
sexCallBack;
},
child: Text('调查性别(VoidCallback)'),
),
RaisedButton(
onPressed: () {
ageCallBack(23);
},
child: Text('调查年龄(ValueSetter)'),
),
],
),
);
}
}
看一下VoidCallback、ValueChanged
的源码可以知道
typedef VoidCallback = void Function()
typedef ValueSetter<T> = void Function(T value)
本质上VoidCallback、ValueChanged
就是typedef
的一种写法而已,只是Flutter帮我们做了一层封装
格物致知篇
旨在通过举例或查看源码,进行源码解析,探究某项技术的原理或实现步骤
说起回调函数,其实回调函数在我们日常工作中的角色是非比寻常的,回调函数承担着页面组件之间交互动作、数据传递等重要的工作,同时回调方法在Flutter的状态管理中也是承担着非常重要的角色。
当数据发生改变时,通过回调方法可以改变外部变量,再通过setState()
方法进行页面刷新。
由于typedef只是一个方法的修饰符、关键字而已,所以并没有源码可以进行分析,在此我们只对其用法和意义进行一个说明
其实本菜鸡理解为:typedef
修饰的方法,可以当做类C方法中方法指针,被其修饰过之后的方法本身就可以理解为和正常变量用法一直,可以当做其他方法的输入参数或返回参数进行传递。
由于Flutter页面(或组件)间的传值有很多种实现方式,而官方最推崇的也是typedef
,所以这里只对typedef
进行了一个简单的介绍用法。
豹尾小结篇
聊天吹水环节
今天的文章主要对状态管理进行一个简单分析,做一个抛砖引玉,下一篇将对Flutter中的状态管理进行详细剖析,包括现在已经在用的一些优秀的状态管理库和Fluuter内置的状态管理方法。
害, 又水了一篇文章 :)
我是努力成为Flutter架构的Flutter小菜鸡,我为自己带盐!