flutter组件采用函数式响应框架构建,它的灵感来自于React。它设计的核心思想是组件外构建UI,简单解释一下就是组件鉴于它当前的配置和状态来描述它的视图应该是怎样的,当组件的状态发生改变,组件会重构它的配置和状态(这些配置和状态是在组件外部重构的,内部的配置和状态都不可变的)。而后底层框架会将最新的配置和状态与先前的作对比,由此产生一个最小的差值,并由此差值来决定底层渲染树从旧状态过分到新状态。react
首先咱们先来写一个最基本的flutter应用吧。android
1.在适当的目录执行:git
flutter init -o my_hello_world_app
2.替换my_hello_world_app/lib/main.dart文件中的内容:github
import 'package:flutter/material.dart'; void main() => runApp(new Center(child: new Text('Hello, world!')));
3.在my_hello_world_app目录下执行:架构
flutter start
4.你将会在手机上看到:
若是你能一切顺利的来到这里,那么恭喜你,你已经成功使用flutter开发了一个android的应用,虽然这个应用看上去比较单一。app
main方法是这个应用的入口,要运行一个应用的话须要使用runApp方法,它接收一个Widget控件做为参数,而且把这个控件做为控件树的根节点。在咱们这个例子里,控件树里有两个控件,Center
控件和它的子节点Text
。一般状况下框架会强制将根控件充满整个屏幕,因此相对的Text控件就以屏幕为中心了。框架
重要概念:
在编写flutter应用的时候,一般状况下须要自定义组件,这些组件继承自StatelessComponent
或StatefulComponent
,选择要继承哪个取决于这个组件是否须要管理状态和配置。一个组件的主要工做就是实现build
方法,这个方法用来反应该组件在其余组件中的表现形式。最后底层框架会统一从上到下调用build方法直至渲染树的最底层。less
flutter提供了一套完备的基本控件,最经常使用的有以下几个:函数
Positioned
控件来指定组件在Stack中的顺序。BoxDecoration
来进行外观装饰,装饰内容能够是背景,边框和阴影等。Container也有外边距,内边距等属性,也能够约束自身的大小,另外值得一提的是Container还能够利用矩阵在三维控件内作转换。下面结合一些基本的控件来自定义咱们的组件并构建应用:
修改main.dart代码以下字体
import 'package:flutter/material.dart'; class MyToolBar extends StatelessComponent { //(3) MyToolBar({ this.title }); final Widget title; //(6) Widget build(BuildContext context) { return new Container( height: 56.0, padding: const EdgeDims.symmetric(horizontal: 8.0), decoration: new BoxDecoration( backgroundColor: Colors.blue[500] ), child: new Row([ new IconButton(icon: 'navigation/menu'), new Flexible(child: title), new IconButton(icon: 'action/search'), ]) ); } } class MyScaffold extends StatelessComponent { //(4) Widget build(BuildContext context) { return new Material( child: new Column([ new MyToolBar( title: new Text('Example title', style: Typography.white.title) ), new Flexible( child: new Center( child: new Text('Hello, world!') ) ) ]) ); } } void main() { runApp(new MaterialApp( //(1) title: 'My app', routes: <String, RouteBuilder>{ //(2) '/': (RouteArguments args) => new MyScaffold() //(5) } )); }
同时确保flutter.yaml
文件内容以下:
name: my_app material-design-icons: - name: action/search - name: navigation/menu
咱们先来运行一下这个应用:
恭喜你,顺利存活。
代码解释以下:
MaterialApp
是整个应用的主题控件,通常咱们自定义的组件要写在它里面才会有Material的主题风格routes
的做用是页面导航做用,/
表示应用打开的第一个页面。MyToolBar
是咱们自定义的一个无状态组件,经过build方法,咱们能够看出其最外层是一个Container
控件,控件高为56dp,左右内边距8dp,它由一个BoxDecoration
作修饰,修饰内容是将背景颜色改成Colors.blue[500]
这种颜色。Container的内部是一个Row
,Row的两端分别是一个图标按钮,中间是另外一个控件Flexible
,它的做用是填充掉Row的剩余部分。在Flexible中传入的是title
这个内部字段。MyScaffold
组件将其子节点用垂直的方式组织起来,在Column
的第一个位置是咱们自定义的MyToolBar
,在构造MyToolBar的时候将一个Text
控件做为它的命名可选参数title的值传递进去。在Column的第二个位置是一个Flexible
用来填充剩余的空间,在Flexible里面放置了一个Center
组件,Center组件里则是一个Text用来显示“Hello,World”。MyScaffold
。这种flutter这种层层包裹的感受就是前面提到的组件外构建UI一小部分含义,眼尖的同窗可能已经看到(6)处的title使用的是final修饰符,这里要说明一下继承自StatelessComponent的组件,如内部有配置,属性或状态的统一须要使用final修饰符,表示这个组件自己本身是无状态的,须要依赖它外部的其余组件。这也是'组件外构建UI'最重要的含义所在。
上面那个应用咱们使用本身的组件进行应用开发,发现应用总体美观度不高。是由于flutter中应用界面会撑满整个屏幕,因此有一部份内容可能会被状态栏挡住。其实flutter提供了一系列的控件供开发人员开发Material风格的应用,这之中就有MaterialApp
,Scaffold
,ToolBar
和FloatingActionButton
等。下面看一个使用了这些控件的例子:
修改main.dart内容以下:
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp( title: 'Flutter Tutorial', routes: {'/': (RouteArguments args) => new TutorialHome()})); } class TutorialHome extends StatelessComponent { Widget build(BuildContext context) { return new Scaffold( toolBar: new ToolBar( left: new IconButton(icon: 'navigation/menu'), center: new Text('Example title'), right: [new IconButton(icon: 'action/search')]), body: new Center(child: new Text('Hello, world!')), floatingActionButton: new FloatingActionButton(child: new Icon(icon: 'content/add'))); } }
修改flutter.yaml
文件内容以下:
name: my_app material-design-icons: - name: action/search - name: content/add - name: navigation/menu
运行结果以下:
如今咱们的应用看起来是否是更像是一个Material Design
的应用了?咱们使用的Scaffold
和ToolBar
让ToolBar自带了阴影而且字体风格有有了调整。另外还加上了FloatingActionButton
。
本文主要讲解flutter种的无状态组件,即继承自StatelessComponent
的组件。它们的特色就是本身内部的配置属性都使用final修饰符,强制其自身没法修改自身状态。下一节将讲解StatefulComponent
。