之前把Dart的语法都过了一遍,并且写了一篇博客来记录了一下,接下来就是Flutter部分了
一、基本特性、代码结构理解
Flutter Widget采用现代响应式框架构建,就是跟React有些类似,中心思想是用widget构建UI,当UI状态发生变化时,刷新页面来达到显示新页面的目的,如果写过ReactNative会好理解很多
我们首先来看一下HelloWorld程序:
import 'package:flutter/material.dart';
void main() {
runApp(
new Center(
child: new Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
乍看之下这个结构有点奇怪,看起来很繁琐,但实际上,我们拆分、重组一下就可以变成很清晰的结构
void main() {
//定义一个文字组件,并设置文字内容
var text = Text("Hellow,World");
//设置文字组件内容的朝向
text.textDirection = TextDirection.ltr;
//定义一个居中组件
var center = Center();
//将居中组件的内容设置为文字
center.child = text;
//在启动组件中将center组件穿进去显示
runApp(
center
);
}
只是这个代码在实际执行时是不行的,因为Text的textDirection属性和Center的child属性都是final的,无法动态设置,那么我们可以再重组一下
void main() {
//创建好文字组件并在构造器中设置默认的内容以及文字方向
var text = Text("Hello,World",textDirection: TextDirection.ltr);
//创建居中组件并在构造器中设置child的内容
var center = Center(child: text);
//将要现实的组件穿进去
runApp(
center
);
}
这样重组之后是不是清晰多了?那么可读性方面的基本问题算是解决了
二、基础组件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
可以使用矩阵在三维空间中对其进行变换。
可以用这些基本组件来写一个demo,我就直接把中文网的demo贴出来了
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(),
));
}
我们来整理一下:
import 'package:flutter/material.dart';
class MyAppBar extends StatelessWidget {
MyAppBar({this.title});
//标题栏容器的高度
static const double appBarHeight = 56;
//标题栏容器的形状以及颜色
static var box = BoxDecoration(color: Colors.blue[500]);
//容器的内边距
static const padding = EdgeInsets.symmetric(horizontal: 8.0);
//标题中的文字组件, Widget子类中的字段往往都会定义为"final"
final Widget title;
@override
Widget build(BuildContext context) {
//第一个按钮,菜单
var menuIcon = IconButton(icon: Icon(Icons.menu),
tooltip: "Navigation menu",
onPressed: null,);// null 会禁用 button
//第二个是组件,填充标题
var expand = Expanded(child: title,);
//第三个也是图标
var searchIcon = IconButton(icon: Icon(Icons.search),
tooltip: "Search",
onPressed: null,);
//然后排列好三个按钮的顺序
var bars = <Widget>[menuIcon,expand,searchIcon];
//设置排列方向
var rowViews = Row(children:bars,);
//最后设置容器
var container = Container(height: appBarHeight,
padding: padding,
decoration: box,
child: rowViews,);
return container;
}
}
class MyScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
//标题部分
//标题文字
// var style1 = TextStyle(color: Colors.black,fontSize: 30);
var appBarTitle = Text('Example title',style: Theme.of(context).primaryTextTheme.title,);
var appBar = MyAppBar(title: appBarTitle,);
//布局部分
var contentText = Text("Hello, world!");
var centerText = Center(child: contentText,);
var expand = Expanded(child: centerText,);
//排好顺序放进数组
var views = <Widget>[appBar,expand];
//标题和布局部分竖直排列
var column = Column(children: views,);
//最外层布局
var material = Material(child: column,);
// Material 是UI呈现的“一张纸”
return material;
}
}
void main() {
runApp(new MaterialApp(
title: 'My app', // used by the OS task switcher
home: new MyScaffold(),
));
}
这样是不是清晰了很多,这样的话UI布局这一块其实就很明了了,其他的都是组件的熟悉方面的了