Flutter—分久必合,结束百家争鸣的使者
Flutter致命优势
当今大前端开发天下,百家争鸣,玲琅满目的框架 、插件害苦了开发人员。
如果你是一名移动端或者前端开发人员,,你还不知道或者还在观望Flutter,这是件多么可怕的事情。
之前对于Flutter我也是持观望态度,随着1.0、1.2版本的发布,果断入坑,理由很简单:
- Flutter是自己渲染界面(区别于React Native以及Weex),这一点势必打破手机碎片化问题,不管是哪个厂商的安卓手机,也不管是ios还是安卓,画完UI,长相一个样,几乎不用适配。
- 第二点就厉害了,Flutter支持web开发、桌面(windows、macOS)开发、移动端(ios、安卓),以及谷歌将来要出的新系统Fuchsia,统统支持。
当然人无完人,flutter 现在还是幼婴阶段,插件、控件之类的还不是很多,以及热修复暂时还不支持,不过这些都是迟早解决的事。
入坑以来,发现Flutter 的页面不像安卓那样明确,安卓中就是Activity,IOS中就是UIViewController,H5中就是一个route,我们项目开发基本都会有一个BaseActivity/BaseViewController,今天就为各位带来和其功能以及使用方式差不多的BaseWidget。
BaseWidget
BaseWidget 生命周期
话不多说,先上视频。


- 左图是 一个页面里面嵌套着三个Tab页切换的效果
- 右图是一个三级路由跳转和回退的效果,以及公用的错误页面、无数据页面和loading页面(loadiing页面可以用dialog替换)。
- 下面两幅图分别是这两个效果中 跳转和切换时 每个页面的生命周期情况


就问 熟不熟悉!熟不熟悉 ! 相信每一个安卓开发人员都很熟悉这种log日志,也是安卓入门必备的技能。
BaseWidget 实现功能
看完效果,我来描述一下BaseWidget所能轻松实现的功能。
- 开发的时候,写一个类继承BaseWidget,就会让我们实现必要的抽象方法,俗称模板模式,当然,内嵌页面需要继承BaseInnerWidget,要做的事一目了然
- 从一个页面A跳转到B的时候,A会调用onPause方法,B会调用onCreate和onResume方法,从B回到A的时候,A会调用onResume方法,B会调用onPause和onDestory方法 ,onCreate中放一些数据初始化,onResume中就放一下网络请求,每次回到页面都会发起请求,onPause和onDestory分别是离开页面和销毁页面,可以自己根据需求来完善方法。
- 状态栏TopBar可以轻松隐藏和设置颜色以及以图片作为背景,
- 导航栏AppBar同样可以轻松隐藏和设置背景颜色(图片),其中导航栏中的左边返回键、中间的大标题、右面的小标题,可以随意设置隐藏和现实,当然可以重写他们的方法,随意设置自己的Widget,实现高度定制。
- 内置了一个 错误加载页面 ,网络加载出错的时候 ,可以调个方法就显示,不用每个页面都写错误页面,避免需求变更时束手无策。
- 内置一个无数据页面,和错误页面 使用方法和功能差不多
- 内置了loading加载 页面 ,功能同上,觉得这个没必要的,可以自己用dialog替代~
- 监听app退到后台和从后台返回到前台,要做什么功能在BaseWidget的方法里面直接写就好了
- 重中之重,有了一个基类,拓展性就很高很高了~
新写一个类 ,创建好是这个样子的,简约而大气的模板模式,可以随心所欲的写代码了。
class FirstPage extends BaseWidget {
@override
BaseWidgetState<BaseWidget> getState() {
// TODO: implement getState
return _FirstPageState();
}
}
class _FirstPageState extends BaseWidgetState<FirstPage> {
@override
Widget buildWidget(BuildContext context) {
// TODO: implement buildWidget
return null;
}
@override
void onCreate() {
// TODO: implement onCreate
}
@override
void onPause() {
// TODO: implement onPause
}
@override
void onResume() {
// TODO: implement onResume
}
}
BaseWidget 实现思路
入坑Flutter的时候发觉Flutter的生命周期不是那么明确。
Flutter中所谓的生命周期是在State中,如下简单几个
- initState 创建之初调用一次 类似于onCreate
- didChangeDependencies 在initState之后调用,可以在这个方法中跨组件拿到数据。
- didUpdateWidget 当组件的状态改变的时候就会调用,比如调用了setState.
- build 创建Widget的地方,在离开和回到页面的时候都会调用。
- deactivate 在离开和回到页面的时候都会调用。
- dispose 销毁的时候调用
打日志的时候发现很乱,尤其的build和deactivate两个方法,跳转和回到页面都会调用到,有点像onPause和onResume的集合体,所以就借用了数据结构中的Stack栈 在页面创建的时候存在Stack中,离开的时候移除Stack,然后根据页面存在栈中的位置,结合build和deactivate 调用时机,写出了真正意义上的onPaue和onResume方法。
@override
void initState() {
NavigatorManger().addWidget(this);//入栈
}
@override
void dispose() {
NavigatorManger().removeWidget(this);//出栈
super.dispose();
}
不过这里出现了个情况,就是当BaseWidget作为内部页面嵌入的时候,自己的生命周期不明确,而且也影响外部页面的生命周期,索性就单独整了一个BaseInnerWisget作为内嵌页面的基类,有点类似BaseFragment,不过他的生命周期需要在外部页面中完善些方法才能正确,强迫症的同学可以自己在封装一下~具体使用方法已上传代码,可自行发挥。
生命周期整完以后,就是一些基础布局搭建了,
布局搭建,就是在基类里面的Build方法中先内置了几个基本控件,然后预留一个抽象方法给子类搭建自己的布局。
Widget _getBaseView(BuildContext context) {
return Column(
children: <Widget>[
_getBaseTopBar(),//状态栏布局
_getBaseAppBar(),//导航栏布局
Container(
width: getScreenWidth(),
height: getMainWidgetHeight(),//子类布局可用的高度
color: Colors.white, //背景颜色,可自己变更
child: Stack(
children: <Widget>[
buildWidget(context),//子类的布局
_getBaseErrorWidget(),//错误页面布局
_getBaseEmptyWidget(),//空页面布局
_getBassLoadingWidget(),//加载中布局
],
),
),
],
);
}
剩下的事情就是往各个方法里面填写对应的界面,以及暴露出方法让子类修改属性,无非就是设置下 文案,图片,隐藏和显示,都是很基础的啦,具体实现可以自己看代码哈,一定难不倒聪明的你!
作为开发人员,我希望把功能掌握在自己手里,而不是sdk手里,愉快的发车吧!
源码和具体说明已经上传至github欢迎star、fork。
Flutter/安卓开发交流群:661614986,期待您的加入!