作者簡介: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小菜雞,我為自己帶鹽!