一、页面Page规范前后效果对比
我们先从页面开始(以登录页的优化为例),然后逐步的从点到面铺开描述。
目标:页面布局、控件定义、事件处理分离。
1、演示的Page的UI图
2、规范前的效果
规范前:未进行任何处理的时候,你的代码是这样的。
3、规范后的效果
规范后**:按规范处理后你代码的效果是这样的,
可见通过处理后Page的整体代码更加简洁了。
二、页面Page开发规范的细则
1、规范一:将每个Widget的定义整理到单独的函数里
写:
不写:
2、规范二:将各个Widget组成界面的布局放到widgets()
方法里处理
写法如下:
如此通过以上两步后,Widget build
中的代码即会变为如下:
如此通过以上几个拆分,我们的Page页面就显得很简洁和很好维护了。
3、规范三、Widget的封装
细心的你,可能发现了我们这里有一个系统没有的LoginTextField
文本框类。是的,该类是我们自定义封装到Package后来使用的。
对于一个控件怎么封装,详情查看之前的文章《Flutter进阶(2):控件Widget的自定义与封装》
三、页面Page规范小结
- 1、Widget build方法
在build
方法里尽量用最少的代码实现整体视图。如下,我们将登录页中的所有Widget通过loginWidgets()
函数封装起来。
- 2、各个Widget组成的视图布局
在loginWidgets()
方法里实现页面Widgets的布局。而对于Widget的定义为了不让页面布局与控件定义因写在一堆,而造成代码一大坨。我们对每个Widget单独提供定义的函数,如userNameTextField()
即为定义用户文本框的函数。
3、抽离每个Widget的定义
4、封装单个Widget
四、业务逻辑的开发规范
说完了页面上的Widgets的开发规范,下面就轮到页面上的业务逻辑的开发规范了。
拿登录页需要获取上次登录的账号来说,它的业务是getDefaultLoginAccountAction
,下面以混编时候的项目为例
1、未去解耦业务时候的登录页
getDefaultLoginAccountAction
在Page中的实现一般为:
/// LoginPage.dart 中的业务代码
static const callNativeMethodChannel = const MethodChannel('com.dvlproad.ciyouzen/callNativeLoginMethodChannel');
Future _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 {}
}
相应的它的调用为:
/// LoginPage.dart 未去解耦时候的登录页
class MyLoginPage extends StatefulWidget {
MyLoginPage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyLoginPageState createState() => _MyLoginPageState();
}
class _MyLoginPageState extends State {
@override
void initState() {
// TODO: implement initState
super.initState();
print("Login Page initState");
_getDefaultLoginAccountAction();
}
// other things
}
可见上述的业务处理getDefaultLoginAccountAction
中,掺杂了对页面Page的setState
操作,这不适合我们以后只对业务或者只对页面做修改的处理。所以下面我们将它们解耦。
2、解耦业务时候的登录页
[图片上传失败...(image-1a7cf4-1552384194828)]
getDefaultLoginAccountAction
在ChannelModel中的实现一般为:
/// LoginChannelModel.dart 文件
Future
相应的它的调用为:
/// LoginPage.dart 解耦时候的登录页
class MyLoginPage extends StatefulWidget {
MyLoginPage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyLoginPageState createState() => _MyLoginPageState();
}
class _MyLoginPageState extends State {
@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的数据规范
在使用Flutter与原生项目混编的时候,因为涉及到数据传输,所以我们有必要在前期就对传输数据的进行规范统一。
此步略。
结束语
时间仓促,后续会再完善。