[Flutter-前端视角]dart 语言学习笔记(1)

[Flutter-前端视角]dart 语言学习笔记(2)

[Flutter-前端视角]dart 语言学习笔记(3)

对应的前端 HTML 标签

HTML 里面的标签在 flutter 里面叫做Widget,但是Widget并不是 html 里面的标签,因为 css 里面的一些属性也处理成相应的Widget了。

也就是说Widget包含标签和 CSS 属性

1. h1 ~ h6,p,span 文字相关标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Text类,可以看作是块级的文字显示
new Text(
"Lorem ipsum",
style: new TextStyle(
fontSize: 24.0
fontWeight: FontWeight.w900,
fontFamily: "Georgia",
),
)

// 行内文字使用TextSpan类
new TextSpan(
style: bold24Roboto,
children: <TextSpan>[
new TextSpan(text: "Lorem "),
new TextSpan(
text: "ipsum",
style: new TextStyle(
fontWeight: FontWeight.w300,
fontStyle: FontStyle.italic,
fontSize: 48.0,
),
),
],
)

这两个类都只能处理文字样式,fontsize, fontweight 等。间距等属性要借助其他类去处理

2. img 标签

1
2
3
4
5
6
7
8
9
10
// 网络图片
Image.network('networkUrl')
// or
NetworkImage('networkUrl')

// 本地图片
Image.asset('assetsUrl')
// or
AssetImage('assetsUrl')

第一个使用方式是Image类的命名构造函数,第二种用法是针对命名构造函数单独声明的类,没什么区别;

3. div 标签

1
2
3
4
5
6
7
8
new Container(
color: Color(0xFFDDDDDD), // decoration
width: 100.0,
height: 100.0,
padding: EdgeInsets.all(10.0), // decoration
margin: EdgeInsets.all(10.0), // decoration
child: new Text('lorem ~~'),
)

等价于 HTML

1
2
3
4
5
6
7
8
9
10
11
12
<style>
.container {
width: 100px;
height: 100px;
background-color: #dddddd;
padding: 10px;
margin: 10px;
}
</style>
<div class="container">
<p>lorem ~~</p>
</div>

Container类,还有其他参数,注释有 decoration 的参数,可以统一在 decoration 参数中实现,decoration 参数和注释有 decoration 的参数是互斥的(如果 decoration 参数存在,其他属性就不需要了,都需要在 decoration 参数中去处理) decoration 参数的类型是实现Decoration类的类或子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
new Container(
decoration: new BoxDecoration(
// color: Colors.red,
gradient: new LinearGradient(
colors: [
Colors.red,
Colors.blue,
],
),
padding: EdgeInsets.all(10.0),
margin: EdgeInsets.all(10.0),
border: Border.all(width: 1.0, color: Colors.black),
borderRadius: BorderRadius.circular(8.0),
),
)

decoration 参数 <===> HTML 属性 background, border, border-radius, margin, paddingbox-shadow

HTML 中的常见场景在 flutter 中的实现

flutter 文档于 web 开发者视角

这里我讲一些没有介绍的, 以及我学习过程中遇到的

1. 复杂背景的实现

最简单的办法是使用图片作为背景, 但是使用图片有些弊端,比如适配~。背景带动画效果的,使用图片也实现不了~

解决思路:通过 Widget 来实现复杂的效果,最终把实现的 Widget 作为页面背景

和 web 开发类比一下:两个 div 标签,一个 div 用来实现背景,一个 div 装内容,最终通过定位,使得两个 div 重叠在一起,通过 zindex 控制层级,最终达到想要的视觉效果

当然在 flutter 里面的思路也是一样的:不同的是 flutter 中有一个 Widget,叫Stack
可以允许其子 widget 简单的堆叠在一起

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Color(0xFF0071EF),
boxShadow: <BoxShadow>[
new BoxShadow (
color: const Color(0xFF0071EF),
offset: new Offset(0.0, 16.0),
blurRadius: 24.0,
spreadRadius: -16.0
),
]
),
), // 实现boxshadow
Row(
children: <Widget>[
new Expanded(
flex: 1,
child: new ClipPath(
clipper: new ClipperOne(),
child: Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
begin: Alignment.bottomRight,
end: Alignment.topRight,
colors: [
Color(0xFF0071EF),
Color(0xFF2688F6),
],
)
),
height: 184.0,
),
),
),
new Expanded(
flex: 1,
child: new ClipPath(
clipper: new ClipperTwo(),
child: Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
begin: Alignment.centerRight,
end: Alignment.bottomLeft,
colors: [
Color(0xFF0071EF),
Color(0xFF2688F6),
],
)
),
height: 184.0,
),
),
),
],
), // 复杂的背景
Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0, vertical: 32.0),
child: Text('lorem content'),
), // 上层的内容
],
)

2. 滚动

web 中可以直接通过 overflow 来实现,在 flutter 中提供的特定功能的 Widget
SingleChildScrollView, ListView 等~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
new ListView.builder(
padding: new EdgeInsets.all(8.0),
itemExtent: 20.0,
itemBuilder: (BuildContext context, int index) {
return new Text('entry $index');
},
)

SingleChildScrollView(
child: Column(
children: <Widget>[
appBarColumn(), // 自定义组件
swiperCard(), // 自定义组件
actionsCard(), // 自定义组件
],
),
)

3. 滚动容器显示滚动条

使用ScrollBar这个 Widget

1
2
3
4
5
6
7
8
9
Scrollbar(
child: new ListView.builder(
padding: new EdgeInsets.all(8.0),
itemExtent: 20.0,
itemBuilder: (BuildContext context, int index) {
return new Text('entry $index');
},
)
)

4. 点击事件

InkWell或者 button 相关的 Widget 都有 onPressed 或 onTap 参数来实现点击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
InkWell(
onTap: () { print('onTap'); },
child: Container(
child: Text('tap')
),
)

FlatButton(
onPressed: () { print('onPressed'); },
child: Text('button'),
)
// 图片点击跳转 没有a标签之类的Widget, 可以考虑自定义Widget,模拟web方式

InkWell(
onTap: () { Navigator.push(context, route) },
child: Image.asset('assetUrl'),
)

5. 事件监听

flutter 中常用的 Widget

Widgets 目录

  1. Container, BoxDecoration,相当于 div 标签
  2. Text, TextStyle 文字
  3. Flex, Row, Collumn, Expanded, Flexible 使用 flex 布局的相关 Widget
  4. Image 图片
  5. ListView, SingleChildScrollView 滚动容器
  6. FlatButton, RaisedButton, IconButton, FloatingActionButton, PopupMenuButton, ButtonBar 按钮
  7. Padding, Center, Stack, Color 属性相关的 Widget
  8. Icons, Colors, Alignment, Axis 枚举

总结

  1. HTML 通过标签嵌套来实现的 tree 结构,flutter 通过 child 或者 children 参数实现 tree 结构
  2. flutter 中没有 css 中 class 的概念, 想实现样式复用,可以通过自定义 Widget 来实现(虽然可以实现,但是复用率不高,好多样式还是要重复写的,比如背景颜色是红色,不同的 widget 没办法抽离通用 class,这里没有 css 方便)
  3. 等待补充~
  4. 学习过程写的项目
    项目地址:https://github.com/Kntt/flutter-app-study