Flutter 未來發展
提到 Flutter 就不得不提到 Fuchsia 系統,這是一個尚未正式釋出的操作的系統,引用 Android 和 Chrome 的高階副總裁 Hiroshi Lockheimer 在一檔播客節目中對 Fuchsia 的介紹是:
不僅僅是手機和個人電腦,在物聯網的世界裡,越來越多的裝置需要作業系統、新的軟體執行環境等支援。我認為,在具有不同優勢和專業化的諸多作業系統中還存在很大的發展空間。Fuchsia 就是其中之一,所以,請繼續保持關注。
是的,Fuchsia 系統是為物聯網研發的作業系統,物聯網簡稱 IoT,現在全世界都在押注 IoT,包括華為、小米等國內公司。
那 Flutter 和 Fuchsia 又有什麼關係呢?
Flutter 是 Fuchsia 官方指定的唯一UI開發框架。
現在有很多物聯網作業系統 ,Fuchsia 就一定可以脫穎而出嗎?
不一定,未來的事情誰說的準呢,但在我看來 Fuchsia 是最有可能發展起來的物聯網作業系統,因為一個作業系統的發展除了本身優秀以外,最大的阻礙其實是生態,而 Fuchsia 在生態方面具有天然的優勢, 國外的一篇報導曾說:
Google 希望將 Android App 無縫移植到 Fuchsia 上,而且一直在做相關工作。
試想一下,一旦 Google 將 Android App 無縫移植到 Fuchsia 上,其他物聯網作業系統如何與之抗衡。
這裡引用 Google 公眾號底部的一句話送給大家:
預測未來不如創造未來
在跨平臺技術上 Flutter 還有很多競爭對手,比如 HTML5、React Native、Weex、快應用、小程式等,我曾在跨平臺技術發展簡介 中詳細說明了各個跨平臺技術的發展歷史及優缺點。
Flutter 的出現會終結其他跨平臺技術?我想不會的, React Native 發展了這麼多年也沒有完全乾掉 HTML5,應為 HTML5 有其獨特的應用場景,比如 營銷活動場景、新聞或者部落格詳情頁面等,這些場景非常適合 HTML5。因此 Flutter 也不可能終結其他跨平臺技術,總結一句話就是:
未來很長一段時間,將會是跨平臺技術共存的時代,但 Flutter 適用場景更為廣闊。
Flutter 巢狀地獄
現在網路上對 Flutter 吐槽最多大概就是 Flutter “巢狀地獄”寫法了,為什麼會出現這種現象?個人認為最大的原因就是目前大部分開源的 Flutter 專案都是這種巢狀寫法(包括我自己以前也是如此),導致後來的初學者認為這麼寫沒有問題,當專案越來越複雜時,這種巢狀寫法給專案的維護帶來了巨大的挑戰。下面說說如何避免這種巢狀寫法?
比如實現如下效果:
巢狀地獄 的寫法:
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
height: 45,
child: Row(
children: <Widget>[
SizedBox(
width: 30,
),
Icon(
Icons.notifications,
color: Colors.blue,
),
SizedBox(
width: 30,
),
Expanded(
child: Text('訊息中心'),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(50)),
color: Colors.red),
child: Text(
'2',
style: TextStyle(color: Colors.white),
),
),
SizedBox(
width: 15,
),
],
),
),
Divider(),
//類似上面的佈局寫6個
],
);
}
複製程式碼
上面還僅僅是第一項的佈局,下面還有7個,一個30多行程式碼,7個就是200多行的佈局程式碼,這還僅僅是佈局程式碼,如果加上邏輯,都不敢想象啊。
或許有一點封裝思想開發者會將每一個 Item封裝為一個方法,寫法如下:
_buildItem(IconData iconData, Color iconColor, String title, Widget widget) {
return Container(
height: 45,
child: Row(
children: <Widget>[
SizedBox(
width: 30,
),
Icon(
iconData,
color: iconColor,
),
SizedBox(
width: 30,
),
Expanded(
child: Text('$title'),
),
widget,
SizedBox(
width: 15,
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
_buildItem(...),
Divider(),
_buildItem(...),
Divider(),
_buildItem(...),
Divider(),
_buildItem(...),
Divider(),
_buildItem(...),
Divider(),
_buildItem(...),
Divider(),
],
);
}
複製程式碼
這樣看起來好多了,基本解決了巢狀地獄問題,但這樣寫還存在一個非常大的問題-效能問題,一旦其中一個數字發生變化,整個頁面都要重建,Flutter 開發中非常重要的一個原則就是 儘可能少的重建元件,因此將上面封裝到方法中元件變為一個 Widget。
class SettingDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
_SettingItem(
iconData: Icons.notifications,
iconColor: Colors.blue,
title: '訊息中心',
suffix: _NotificationsText(
text: '2',
),
),
Divider(),
_SettingItem(
iconData: Icons.thumb_up,
iconColor: Colors.green,
title: '我贊過的',
suffix: _Suffix(
text: '121篇',
),
),
Divider(),
_SettingItem(
iconData: Icons.grade,
iconColor: Colors.yellow,
title: '收藏集',
suffix: _Suffix(
text: '2個',
),
),
Divider(),
_SettingItem(
iconData: Icons.shopping_basket,
iconColor: Colors.yellow,
title: '已購小冊',
suffix: _Suffix(
text: '100個',
),
),
Divider(),
_SettingItem(
iconData: Icons.account_balance_wallet,
iconColor: Colors.blue,
title: '我的錢包',
suffix: _Suffix(
text: '10萬',
),
),
Divider(),
_SettingItem(
iconData: Icons.location_on,
iconColor: Colors.grey,
title: '閱讀過的文章',
suffix: _Suffix(
text: '1034篇',
),
),
Divider(),
_SettingItem(
iconData: Icons.local_offer,
iconColor: Colors.grey,
title: '標籤管理',
suffix: _Suffix(
text: '27個',
),
),
],
);
}
}
class _SettingItem extends StatelessWidget {
const _SettingItem(
{Key key, this.iconData, this.iconColor, this.title, this.suffix})
: super(key: key);
final IconData iconData;
final Color iconColor;
final String title;
final Widget suffix;
@override
Widget build(BuildContext context) {
return Container(
height: 45,
child: Row(
children: <Widget>[
SizedBox(
width: 30,
),
Icon(iconData,color: iconColor,),
SizedBox(
width: 30,
),
Expanded(
child: Text('$title'),
),
suffix,
SizedBox(
width: 15,
),
],
),
);
}
}
class _NotificationsText extends StatelessWidget {
final String text;
const _NotificationsText({Key key, this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(50)),
color: Colors.red),
child: Text(
'$text',
style: TextStyle(color: Colors.white),
),
);
}
}
class _Suffix extends StatelessWidget {
final String text;
const _Suffix({Key key, this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
'$text',
style: TextStyle(color: Colors.grey.withOpacity(.5)),
);
}
}
複製程式碼
封裝為一個個單獨的小元件,將有變化的元件儘量單獨封裝,這樣就不會重建整個控制元件樹,增強了可讀性和可維護性,而且對效能有很大的提升。
最後總結一句:
雖然 Flutter 一切皆是元件,但並不代表一切都要寫在元件中。
當然這僅僅是我個人的看法,如果您有更好的方法歡迎一起討論,從我做起,規範寫法,為 Flutter 發展貢獻做出一點微不足道的貢獻。
交流
老孟Flutter部落格地址(330個控制元件用法):laomengit.com
歡迎加入Flutter交流群(微信:laomengit)、關注公眾號【老孟Flutter】: