Android控件 vs Flutter控件

一. 开始

在Android中View是所有控件的基础, 在Flutter中与View对等的是Widget. 但Widget又不同于Android中的views. 在Flutter中你可以声明构造界面.

Flutter中的控件不能修改, 一直到它们需要改变. 当状态发生变更, Flutter的底层会重新创建一颗新的控件树实例. 而在Android中控件绘制一次就不再绘制, 直到invalidate被调用.

由于不可变性, Flutter的控件很轻量. 因为它们不是视图本身,也不是直接绘制任何东西,而是对UI及其语义的描述. 最终才会被构造成实际的试图对象.

二. Android控件

常用基础控件View, TextView, Button, ImageView, 其它控件如ProgressBar, SeekBar等.
这些控件都继承自View. 基础控件不够用时, 可继承这些控件实现自己想要的特性.

在android中存在5种基本布局

  • 线性布局(LinearLayout)
  • 相对布局(RelativeLayout)
  • 表格布局(TableLayout)
  • 帧布局(FrameLayout)
  • 绝对布局(AbsoluteLayout)

TableLayout和AbsoluteLayout我基本没有用到. LinearLayout用于布局水平一行或者纵向一行.
FrameLayout用于布局有层次的界面, 可以简单设置居中. 更复杂控件间的相对关系使用RelativeLayout布局.

FrameLayout性能会好于RelativeLayout, 当FrameLayout无法解决的时候才用RelativeLayout
RelativeLayout通过相对关系也能布局出LinearLayout的界面, 但不如LinearLayout直观

列表可滑动滑动布局ScrollView/ListView/GridView/RecyclerView/ViewPager.

上述控件继承自ViewGroup, ViewGroup又继承于View 相对于继承View的控件, 前者内部可包含子控件, 而后者不行.前者一般会实现onLayout和onMeasure, 来控件子控件的布局和大小. 这些布局不够用时, 也可继承这些控件实现自己想要的特性.

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

  • 宽度(layout_width)
  • 高度(layout_height)
  • 背景(backgroud)
  • 内间距(padding)
  • 外间距(margin)
  • 可见性(visibility)
  • 位于父控件的位置(layout_gravity)
  • 内部子控件的位置(gravity, 继承自ViewGroup的才有)
  • 点击事件(onClick)
  • 动画属性(alpha/rotation/scale)

三. Flutter控件

flutter中的控件非常多, 每一种布局只具备特定的特性. 功能划分的非常细. 最大的不同也正是这点, 基本控件不再拥有通用属性,比如背景, 点击事件等, 这些都被独立出来成为单独的控件.

举个简单例子如下

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中, 属性都被提取成一个控件了, GestureDetector负责处理点击事件, Container负责大小和背景, Center负责居中.Text仅仅只有文字相关的属性, 这样Android一个简单的控件在Flutter中需要嵌套很多层才能实现. 但好处就是划分的很细, 可以任意组合.

基本的显示控件有Text, Image, Icon, RaisedButton等.属性功能控件有Container, Padding, Center, Align, FittedBox等.这些都是Single-child控件. 就是child属性指向为Widget.

布局控件有Row, Column, Stack, IndexedStack, GridView, ListView等.这些都是Multi-child控件. 就是child属性指向为<Widget>[].

四. 实现自定义控件

在Android中通常是继承View或其它基于View的控件. 然后重写其中的方法, 来获取想要的行为.

在Flutter中, 你只需要组合各种小组件而不是继承. 某种程度上类似于实现Android中的一个自定义ViewGroup. 各种组件单元都已经存在, 你只是提供一种不同的行为, 比如, 重新定义布局逻辑.

举个例子: 你想实现一个在构造时获取文字的CustomButton. 你可以通过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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,561评论 25 707
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,194评论 0 17
  • 很多时候,一本书,一幅画,一段音乐,静静的绘画,静静的思考,静静中把往事一丝一缕的整理。时光能给我们的,唯有...
    图妈0302阅读 283评论 0 0
  • 诗书继世長, 忠厚传家远。
    喜亭_bf8f阅读 144评论 2 7