Android控件 vs Flutter控件

一. 開(kāi)始

在Android中View是所有控件的基礎(chǔ), 在Flutter中與View對(duì)等的是Widget. 但Widget又不同于Android中的views. 在Flutter中你可以聲明構(gòu)造界面.

Flutter中的控件不能修改, 一直到它們需要改變. 當(dāng)狀態(tài)發(fā)生變更, Flutter的底層會(huì)重新創(chuàng)建一顆新的控件樹(shù)實(shí)例. 而在Android中控件繪制一次就不再繪制, 直到invalidate被調(diào)用.

由于不可變性, Flutter的控件很輕量. 因?yàn)樗鼈儾皇且晥D本身站楚,也不是直接繪制任何東西,而是對(duì)UI及其語(yǔ)義的描述. 最終才會(huì)被構(gòu)造成實(shí)際的試圖對(duì)象.

二. Android控件

常用基礎(chǔ)控件View, TextView, Button, ImageView, 其它控件如ProgressBar, SeekBar等.
這些控件都繼承自View. 基礎(chǔ)控件不夠用時(shí), 可繼承這些控件實(shí)現(xiàn)自己想要的特性.

在android中存在5種基本布局

  • 線性布局(LinearLayout)
  • 相對(duì)布局(RelativeLayout)
  • 表格布局(TableLayout)
  • 幀布局(FrameLayout)
  • 絕對(duì)布局(AbsoluteLayout)

TableLayout和AbsoluteLayout我基本沒(méi)有用到. LinearLayout用于布局水平一行或者縱向一行.
FrameLayout用于布局有層次的界面, 可以簡(jiǎn)單設(shè)置居中. 更復(fù)雜控件間的相對(duì)關(guān)系使用RelativeLayout布局.

FrameLayout性能會(huì)好于RelativeLayout, 當(dāng)FrameLayout無(wú)法解決的時(shí)候才用RelativeLayout
RelativeLayout通過(guò)相對(duì)關(guān)系也能布局出LinearLayout的界面, 但不如LinearLayout直觀

列表可滑動(dòng)滑動(dòng)布局ScrollView/ListView/GridView/RecyclerView/ViewPager.

上述控件繼承自ViewGroup, ViewGroup又繼承于View 相對(duì)于繼承View的控件, 前者內(nèi)部可包含子控件, 而后者不行.前者一般會(huì)實(shí)現(xiàn)onLayout和onMeasure, 來(lái)控件子控件的布局和大小. 這些布局不夠用時(shí), 也可繼承這些控件實(shí)現(xiàn)自己想要的特性.

上述所有控件都有的屬性有

  • 寬度(layout_width)
  • 高度(layout_height)
  • 背景(backgroud)
  • 內(nèi)間距(padding)
  • 外間距(margin)
  • 可見(jiàn)性(visibility)
  • 位于父控件的位置(layout_gravity)
  • 內(nèi)部子控件的位置(gravity, 繼承自ViewGroup的才有)
  • 點(diǎn)擊事件(onClick)
  • 動(dòng)畫(huà)屬性(alpha/rotation/scale)

三. Flutter控件

flutter中的控件非常多, 每一種布局只具備特定的特性. 功能劃分的非常細(xì). 最大的不同也正是這點(diǎn), 基本控件不再擁有通用屬性,比如背景, 點(diǎn)擊事件等, 這些都被獨(dú)立出來(lái)成為單獨(dú)的控件.

舉個(gè)簡(jiǎn)單例子如下

Android例子

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:onClick="xxx"
        android:gravity="center"
        android:text="按鈕"
        android:textSize="18sp"
        android:textColor="0xffffffff"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:background="0xff808080"/>
</LinearLayout>

Flutter例子

var layout = Column(
  children: <Widget>[
    GestureDetector(
      child: Container(
        width: 100.0,
        height: 40.0,
        color: Color(0xff808080),
        child: Center (
          child: Text(
            '按鈕',
            style: TextStyle(
              color: Color(0xffffffff),
              fontSize: 18.0,
            ),
          ),
        )
      ),
      onTap: () {
        print('clicked');
      },
    ),
  ],
);

可以看出在Flutter中, 屬性都被提取成一個(gè)控件了, GestureDetector負(fù)責(zé)處理點(diǎn)擊事件, Container負(fù)責(zé)大小和背景, Center負(fù)責(zé)居中.Text僅僅只有文字相關(guān)的屬性, 這樣Android一個(gè)簡(jiǎn)單的控件在Flutter中需要嵌套很多層才能實(shí)現(xiàn). 但好處就是劃分的很細(xì), 可以任意組合.

基本的顯示控件有Text, Image, Icon, RaisedButton等.屬性功能控件有Container, Padding, Center, Align, FittedBox等.這些都是Single-child控件. 就是child屬性指向?yàn)閃idget.

布局控件有Row, Column, Stack, IndexedStack, GridView, ListView等.這些都是Multi-child控件. 就是child屬性指向?yàn)?lt;Widget>[].

四. 實(shí)現(xiàn)自定義控件

在Android中通常是繼承View或其它基于View的控件. 然后重寫(xiě)其中的方法, 來(lái)獲取想要的行為.

在Flutter中, 你只需要組合各種小組件而不是繼承. 某種程度上類(lèi)似于實(shí)現(xiàn)Android中的一個(gè)自定義ViewGroup. 各種組件單元都已經(jīng)存在, 你只是提供一種不同的行為, 比如, 重新定義布局邏輯.

舉個(gè)例子: 你想實(shí)現(xiàn)一個(gè)在構(gòu)造時(shí)獲取文字的CustomButton. 你可以通過(guò)RaisedButton組合文字, 而不是繼承RaisedButton.

class CustomButton extends StatelessWidget {
  final String label;

  CustomButton(this.label);

  @override
  Widget build(BuildContext context) {
    return RaisedButton(onPressed: () {}, child: Text(label));
  }
}

然后使用CustomButton就像跟其它Flutter組件一樣:

@override
Widget build(BuildContext context) {
  return Center(
    child: CustomButton("Hello"),
  );
}

五. Android/Flutter映射表

Android Flutter
TextView Text
ImageView Image
Button RaisedButton
LinearLayout Row/Column
FrameLayout/RelativeLayout Stack
ListView ListView
GridView GridView
ViewPager PageView
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市差购,隨后出現(xiàn)的幾起案子箱叁,更是在濱河造成了極大的恐慌张吉,老刑警劉巖仲翎,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甘磨,死亡現(xiàn)場(chǎng)離奇詭異逞泄,居然都是意外死亡患整,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)喷众,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)各谚,“玉大人,你說(shuō)我怎么就攤上這事到千〔常” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵憔四,是天一觀的道長(zhǎng)膀息。 經(jīng)常有香客問(wèn)我,道長(zhǎng)了赵,這世上最難降的妖魔是什么潜支? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮柿汛,結(jié)果婚禮上冗酿,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好裁替,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布项玛。 她就那樣靜靜地躺著,像睡著了一般弱判。 火紅的嫁衣襯著肌膚如雪襟沮。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天裕循,我揣著相機(jī)與錄音臣嚣,去河邊找鬼。 笑死剥哑,一個(gè)胖子當(dāng)著我的面吹牛硅则,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播株婴,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼怎虫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了困介?” 一聲冷哼從身側(cè)響起大审,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎座哩,沒(méi)想到半個(gè)月后徒扶,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡根穷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年姜骡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屿良。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡圈澈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尘惧,到底是詐尸還是另有隱情康栈,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布喷橙,位于F島的核電站啥么,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贰逾。R本人自食惡果不足惜饥臂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望似踱。 院中可真熱鬧,春花似錦、人聲如沸核芽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)轧简。三九已至驰坊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哮独,已是汗流浹背拳芙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留皮璧,地道東北人舟扎。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像悴务,于是被迫代替她去往敵國(guó)和親睹限。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程讯檐,因...
    小菜c閱讀 6,424評(píng)論 0 17
  • 很多時(shí)候别洪,一本書(shū)叨恨,一幅畫(huà),一段音樂(lè)挖垛,靜靜的繪畫(huà)痒钝,靜靜的思考,靜靜中把往事一絲一縷的整理晕换。時(shí)光能給我們的午乓,唯有...
    圖媽0302閱讀 296評(píng)論 0 0
  • 詩(shī)書(shū)繼世長(zhǎng), 忠厚傳家遠(yuǎn)闸准。
    喜亭_bf8f閱讀 155評(píng)論 2 7