Flutter开发者

使你的应用支持Web

2019-10-10

使你的应用支持Web

从flutter 1.9起Flutter就已经从官方角度支持web端了,Web 支持是 Flutter 的代码兼容实现,使用基于标准的 Web 技术呈现:HTML,CSS和JavaScript。通过 Web 支持,你可以将使用 Dart 编写的现有 Flutter 代码编译为可以嵌入浏览器,并部署到任何 Web 服务器上,具有客户端体验的 Web 应用。你可以使用 Flutter 的所有功能,而不需要任何浏览器插件。

Flutter channel

在Flutter中有四个分支分别对应如下,一般情况下我们直接下载下来的是stable分支。

  • master 主分支
  • dev 开发分支
  • beta 测试版本,待发布
  • stable 发布稳定版本

由于flutter web还没有正式发布,还处于beta阶段,所以我们需要先切到beta分支。

直接在命令行依次输入如下命令即可转换为beta分支

1
2
3
$ flutter channel beta
$ flutter upgrade
$ flutter config --enable-web

flutter config执行后需要重启IDE才会在可运行设备中看到web选项,如果是已经存在项目想要支持web只需要在项目跟目录执行如下命令

1
$ flutter create .

打包

在项目根目录使用如下命令即可打包web程序

1
$ flutter build web

项目打包路径在项目/build/web目录下,Flutter将应用所有的界面和逻辑代码都生成到js文件中了。

所以,我们只需要这些代码就可以直接放在我们的网站上运行了,由于生成的逻辑都是由js来处理的,所以我们并不需要什么运行环境使用Nginx代理访问路径就OK了。

我们用一个简单的页面打包并部署到服务器上看下效果

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import 'package:flutter/material.dart';

import 'ItemPage.dart';

void main() {
runApp(new MaterialApp(
home: HomePage(),
));
}

class HomePage extends StatefulWidget {
@override
_MyState createState() => _MyState();
}

class _MyState extends State<HomePage> {
int _currentIndex = 0;
List<ItemPage> items = List();
List<NavItem> _navItem = List();

onIndexChanged(int index) {
setState(() {
_currentIndex = index;
});
}

@override
void initState() {
items.add(ItemPage("主页", Colors.blueAccent));
items.add(ItemPage("归档", Colors.redAccent));
items.add(ItemPage("订阅", Colors.yellowAccent));
items.add(ItemPage("设置", Colors.greenAccent));

_navItem.add(NavItem(title: "主页", icon: Icons.home));
_navItem.add(NavItem(title: "归档", icon: Icons.business_center));
_navItem.add(NavItem(title: "订阅", icon: Icons.cast));
_navItem.add(NavItem(title: "设置", icon: Icons.settings));
super.initState();
}

@override
void dispose() {
// TODO: implement dispose
super.dispose();
}

@override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Drawer(
child: Column(
children: [
DrawerHeader(
padding: EdgeInsets.all(0),
child: Container(
color: Colors.blueAccent,
child: Center(
child: Text(
"Flutter Web",
style: TextStyle(fontSize: 22, color: Colors.white),
),
),
),
),
for (var d in _navItem)
ListTile(
leading: Icon(d.icon),
title: Text(d.title),
selected: _navItem.indexOf(d) == _currentIndex,
onTap: () => onIndexChanged(_navItem.indexOf(d)),
),
],
),
),
VerticalDivider(
width: 1,
thickness: 1,
color: Colors.grey[300],
),
Expanded(
child: Scaffold(
appBar: AppBar(),
body: items[_currentIndex],
floatingActionButton: FloatingActionButton(
child: Icon(Icons.wb_sunny),
),
),
),
],
));
}
}

class NavItem {
final String title;
final IconData icon;

const NavItem({
@required this.title,
@required this.icon,
});
}

class ItemPage extends StatelessWidget {
final String _title;
final Color _color;

ItemPage(this._title, this._color);

@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(30),
color: Colors.white70,
child: Center(
child: Text(
_title,
style: TextStyle(fontSize: 25, color: _color),
),
),
);
}
}

打开地址可以看到跟我们在调试时一样的界面,界面的代码很简单,整个布局是一个Row左边是一个Column,右边是一个Scaffold,实现起来也比较容易[

点击打开测试页面

但是,既然是web页面我们肯定需要兼容不同设备,在不同设备上访问呈现该设备最佳的展示效果才是最好的选择,所以尝试在不同分辨率设备访问该页面,看下有什么变化?

想一想如何实现上面的界面变化?

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

打赏请备注姓名或者昵称,方便我后期统计哦

关注公众号,及时查阅最新文章