Flutter 的 Widget 的基础概念理解
Flutter Widget采用现代响应式框架构建,这是从 React 中获得的灵感,中心思想是用widget构建你的UI。 Widget描述了他们的视图在给定其当前配置和状态时应该看起来像什么。当widget的状态发生变化时,widget会重新构建UI,Flutter会对比前后变化的不同, 以确定底层渲染树从一个状态转换到下一个状态所需的最小更改(译者语:类似于React/Vue中虚拟DOM的diff算法)。
Widgets概念
Flutter里有一个非常重要的核心理念:一切皆为组件,Flutter的所有元素都是由控件构成的。与原生开发中控件所代表的含义不同,Flutter中widget的概念更加广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件,如用于手势检测的 GestureDetector widget、用于应用主题数据传递的Theme等等。而原生开发中的控件通常只是指UI元素。由于Flutter主要就是用于构建用户界面的,所以,在大多数时候,我们可以简单的认为widget就是一个控件,不必纠结于概念。
我们来看一个简单的例子了解一下Widget
import 'package:flutter/material.dart'; void main() { runApp( new Center( child: new Text( 'Hello, world!', textDirection: TextDirection.ltr, ), ), ); }
上面是一个简单的Widget。将一个widget传给runApp函数运行:该runApp函数接受给定的Widget并使其成为widget树的根。 在此示例中,widget树由两个widget:Center(及其子widget)和Text组成。框架强制根widget覆盖整个屏幕,这意味着文本“Hello, world”会居中显示在屏幕上。文本显示的方向需要在Text实例中指定,当使用MaterialApp时,文本的方向将自动设定,稍后将进行演示。
在编写应用程序时,通常会创建新的widget,这些widget是无状态的StatelessWidget或者是有状态的StatefulWidget, 具体的选择取决于您的widget是否需要管理一些状态。widget的主要工作是实现一个build函数,用以构建自身。一个widget通常由一些较低级别widget组成。Flutter框架将依次构建这些widget,直到构建到最底层的子widget时,这些最底层widget通常为RenderObject,它会计算并描述widget的几何形状。
基础 Widget 简单介绍
Flutter有一套丰富、强大的基础widget,其中以下是很常用的:
- Text:该 widget 可让创建一个带格式的文本。
- Row、 Column: 这些具有弹性空间的布局类Widget可让您在水平(Row)和垂直(Column)方向上创建灵活的布局。其设计是基于web开发中的Flexbox布局模型。
- Stack: 取代线性布局 (译者语:和Android中的LinearLayout相似),Stack允许子 widget 堆叠, 你可以使用 Positioned 来定位他们相对于Stack的上下左右四条边的位置。Stacks是基于Web开发中的绝度定位(absolute positioning )布局模型设计的。
- Container: Container 可让您创建矩形视觉元素。container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。
以下是一些简单的Widget,它们可以组合出其它的Widget:
import 'package:flutter/material.dart'; class MyAppBar extends StatelessWidget { MyAppBar({this.title}); // Widget子类中的字段往往都会定义为"final" final Widget title; @override Widget build(BuildContext context) { return new Container( height: 56.0, // 单位是逻辑上的像素(并非真实的像素,类似于浏览器中的像素) padding: const EdgeInsets.symmetric(horizontal: 8.0), decoration: new BoxDecoration(color: Colors.blue[500]), // Row 是水平方向的线性布局(linear layout) child: new Row( //列表项的类型是 <Widget> children: <Widget>[ new IconButton( icon: new Icon(Icons.menu), tooltip: 'Navigation menu', onPressed: null, // null 会禁用 button ), // Expanded expands its child to fill the available space. new Expanded( child: title, ), new IconButton( icon: new Icon(Icons.search), tooltip: 'Search', onPressed: null, ), ], ), ); } } class MyScaffold extends StatelessWidget { @override Widget build(BuildContext context) { // Material 是UI呈现的“一张纸” return new Material( // Column is 垂直方向的线性布局. child: new Column( children: <Widget>[ new MyAppBar( title: new Text( 'Example title', style: Theme.of(context).primaryTextTheme.title, ), ), new Expanded( child: new Center( child: new Text('Hello, world!'), ), ), ], ), ); } } void main() { runApp(new MaterialApp( title: 'My app', // used by the OS task switcher home: new MyScaffold(), )); }
比如一个拥有绘制、定位、调整大小的 widget:Container
在水平方向上排列子widget的列表。ROW
在垂直方向上排列子widget的列表 Column
一个显示图片的widget Image
单一格式的文本 Text
A Material Design icon. Icon
Material Design中的button, 一个凸起的材质矩形按钮 RaisedButton
Material Design布局结构的基本实现。此类提供了用于显示drawer、snackbar和底部sheet的API。Scaffold
一个Material Design应用程序栏,由工具栏和其他可能的widget(如TabBar和FlexibleSpaceBar)组成。 Appbar
上面都是一些基础组件,所以要学习的还是挺多的。