美文网首页Android
Android控件 vs Flutter控件

Android控件 vs Flutter控件

作者: 最近不在 | 来源:发表于2018-08-06 17:30 被阅读250次

一. 开始

在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

相关文章

网友评论

    本文标题:Android控件 vs Flutter控件

    本文链接:https://www.haomeiwen.com/subject/lwmgvftx.html