一次企、頁(yè)面Page規(guī)范前后效果對(duì)比
我們先從頁(yè)面開始(以登錄頁(yè)的優(yōu)化為例)醋火,然后逐步的從點(diǎn)到面鋪開描述悠汽。
目標(biāo):頁(yè)面布局箱吕、控件定義、事件處理分離柿冲。
1茬高、演示的Page的UI圖
2、規(guī)范前的效果
規(guī)范前:未進(jìn)行任何處理的時(shí)候假抄,你的代碼是這樣的怎栽。
3、規(guī)范后的效果
規(guī)范后**:按規(guī)范處理后你代碼的效果是這樣的宿饱,
可見(jiàn)通過(guò)處理后Page的整體代碼更加簡(jiǎn)潔了熏瞄。
二、頁(yè)面Page開發(fā)規(guī)范的細(xì)則
1谬以、規(guī)范一:將每個(gè)Widget的定義整理到單獨(dú)的函數(shù)里
寫:
不寫:
2强饮、規(guī)范二:將各個(gè)Widget組成界面的布局放到widgets()
方法里處理
寫法如下:
如此通過(guò)以上兩步后,Widget build
中的代碼即會(huì)變?yōu)槿缦拢?/p>
如此通過(guò)以上幾個(gè)拆分为黎,我們的Page頁(yè)面就顯得很簡(jiǎn)潔和很好維護(hù)了邮丰。
3、規(guī)范三铭乾、Widget的封裝
細(xì)心的你剪廉,可能發(fā)現(xiàn)了我們這里有一個(gè)系統(tǒng)沒(méi)有的LoginTextField
文本框類。是的炕檩,該類是我們自定義封裝到Package后來(lái)使用的斗蒋。
對(duì)于一個(gè)控件怎么封裝,詳情查看之前的文章《Flutter進(jìn)階(2):控件Widget的自定義與封裝》
三笛质、頁(yè)面Page規(guī)范小結(jié)
- 1吹泡、Widget build方法
在build
方法里盡量用最少的代碼實(shí)現(xiàn)整體視圖。如下经瓷,我們將登錄頁(yè)中的所有Widget通過(guò)loginWidgets()
函數(shù)封裝起來(lái)爆哑。
- 2、各個(gè)Widget組成的視圖布局
在loginWidgets()
方法里實(shí)現(xiàn)頁(yè)面Widgets的布局舆吮。而對(duì)于Widget的定義為了不讓頁(yè)面布局與控件定義因?qū)懺谝欢呀页斐纱a一大坨。我們對(duì)每個(gè)Widget單獨(dú)提供定義的函數(shù)色冀,如userNameTextField()
即為定義用戶文本框的函數(shù)潭袱。
3、抽離每個(gè)Widget的定義
4锋恬、封裝單個(gè)Widget
四屯换、業(yè)務(wù)邏輯的開發(fā)規(guī)范
說(shuō)完了頁(yè)面上的Widgets的開發(fā)規(guī)范,下面就輪到頁(yè)面上的業(yè)務(wù)邏輯的開發(fā)規(guī)范了。
拿登錄頁(yè)需要獲取上次登錄的賬號(hào)來(lái)說(shuō)彤悔,它的業(yè)務(wù)是getDefaultLoginAccountAction
嘉抓,下面以混編時(shí)候的項(xiàng)目為例
1、未去解耦業(yè)務(wù)時(shí)候的登錄頁(yè)
getDefaultLoginAccountAction
在Page中的實(shí)現(xiàn)一般為:
/// LoginPage.dart 中的業(yè)務(wù)代碼
static const callNativeMethodChannel = const MethodChannel('com.dvlproad.ciyouzen/callNativeLoginMethodChannel');
Future<Null> _getDefaultLoginAccountAction() async {
try {
final Map nativeResponse = await callNativeMethodChannel.invokeMethod('getDefaultLoginAccountAction');
final Map nativeResult = callNativeNativeResult(nativeResponse);
setState(() {
userName = nativeResult["userName"];
password = nativeResult["password"];
print(userName + ":" + password);
_usernameController.text = userName;
_passwordController.text = password;
});
} on PlatformException {}
}
相應(yīng)的它的調(diào)用為:
/// LoginPage.dart 未去解耦時(shí)候的登錄頁(yè)
class MyLoginPage extends StatefulWidget {
MyLoginPage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyLoginPageState createState() => _MyLoginPageState();
}
class _MyLoginPageState extends State<MyLoginPage> {
@override
void initState() {
// TODO: implement initState
super.initState();
print("Login Page initState");
_getDefaultLoginAccountAction();
}
// other things
}
可見(jiàn)上述的業(yè)務(wù)處理getDefaultLoginAccountAction
中晕窑,摻雜了對(duì)頁(yè)面Page的setState
操作抑片,這不適合我們以后只對(duì)業(yè)務(wù)或者只對(duì)頁(yè)面做修改的處理。所以下面我們將它們解耦杨赤。
2敞斋、解耦業(yè)務(wù)時(shí)候的登錄頁(yè)
[圖片上傳失敗...(image-1a7cf4-1552384194828)]
getDefaultLoginAccountAction
在ChannelModel中的實(shí)現(xiàn)一般為:
/// LoginChannelModel.dart 文件
Future<Map<String, dynamic>> getDefaultLoginAccountAction() async {
try {
final Map nativeResponse = await callNativeMethodChannel.invokeMethod('getDefaultLoginAccountAction');
final Map nativeResult = callNativeNativeResult(nativeResponse);
return nativeResult;
} on PlatformException {
return null;
}
}
相應(yīng)的它的調(diào)用為:
/// LoginPage.dart 解耦時(shí)候的登錄頁(yè)
class MyLoginPage extends StatefulWidget {
MyLoginPage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyLoginPageState createState() => _MyLoginPageState();
}
class _MyLoginPageState extends State<MyLoginPage> {
@override
void initState() {
// TODO: implement initState
super.initState();
print("Login Page initState");
getDefaultLoginAccountAction().then((nativeResult){
setState(() {
userName = nativeResult["userName"];
password = nativeResult["password"];
print(userName + ":" + password);
_usernameController.text = userName;
_passwordController.text = password;
});
});
}
// other things
}
五、Flutter Channel的數(shù)據(jù)規(guī)范
在使用Flutter與原生項(xiàng)目混編的時(shí)候疾牲,因?yàn)樯婕暗綌?shù)據(jù)傳輸植捎,所以我們有必要在前期就對(duì)傳輸數(shù)據(jù)的進(jìn)行規(guī)范統(tǒng)一。
此步略阳柔。
結(jié)束語(yǔ)
時(shí)間倉(cāng)促鸥跟,后續(xù)會(huì)再完善。