你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了

你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了

你在大公司工作吗?

我知道……你有没有想过(不止一次)“哦,天哪……早上9点,我的一天已经被会议和调bug挤满了!"

是的,几乎每天 ‍!

我敢肯定,每次你在无聊的会议中都会去刷朋友圈!(同意的点赞)

你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了

1.我从哪开始(问题):

我知道每个人在家里都有很多时间做自己的事情,对吧?比如看电视节目、电影、社交媒体……

对于那些有足够财富的人来说,通过聊天、电子邮件和会议交流的唯一途径是什么?

2.研究:

我们都喜欢探索,对吧?

所以,我想“我怎样才能把探索和实际产品结合起来”。

3.工作时间:

好吧,我有8个小时的“办公室工作”。所以,我没有太多的Web知识,因为我主要是一个移动开发人员,现在他们做了更多的管理工作(我知道双方的痛苦),但我知道FlutterFlutter Web目前处于测试版,但,你懂的…!

4.命名产品:

首先,你要为你的产品想一个好名字!


你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了

6.干,干,干!

利用我的空闲时间开始一个新项目总是很有趣的,对吧?但这一次看起来真的很有潜力,范围也没那么大。

选择的工具?!


你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了

当然是用 Flutter


为什么?因为开始一个新的项目、设计和实际完成都很容易

它的发展实在是太快了:身为移动开发者,Web对我来说有点不同,即使我们每天都在使用它,但我们需要考虑的路线(路径)比以往任何时候都多!不仅仅是深层次的联系。

我们在纽约和西蒙以及弗雷特纽约的朋友们开完会后,我突然想到了一个主意。

我的解决方案提供了一个小型的StatefulWidget导航器,没有什么新奇之处,也不是世界上最干净的工作:

<code>class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TMSBAE',
onGenerateRoute: (settings) => NavigatorRoute.route(settings.name),
);
}}/<code>

每一条路径都将来自onGenerateRoute,然后将那个坏小子解析到我们的导航器中。

一旦我走上这条路,我就使用了核心机器学习……或者简称If/Else

<code>@override
void initState() {
super.initState();
Future.delayed(Duration(milliseconds: 0), () {
if (widget.path == '/') {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(), (_) => false);
return;
} else if (widget.path == '/join') {
Navigator.of(context).pushAndRemoveUntil(JoinScreen.route(), (_) => false);
return;
} else if (widget.path.contains('/join/')) {
Navigator.of(context).pushAndRemoveUntil(JoinScreen.routeCode(widget.path.split('/')[2]), (_) => false);
return;
} else if (widget.path == '/bae') {

Navigator.of(context).pushAndRemoveUntil(BaeScreen.route(), (_) => false);
} else if (widget.path.contains('/result/')) { Navigator.of(context).pushAndRemoveUntil(ResultScreen.routeCode(widget.path.split('/')[2]), (_) => false);
} else if (widget.path == '/about') {​
} else {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(), (_) => false);
return;
}
});}}
else {
Navigator.of(context).pushAndRemoveUntil(HomeScreen.route(), (_) => false);
return;
}
});
}/<code>

这样做的目的是避免获得大量的页面,例如:

{URL}/join/djUdmd19m4

Will open:

  • “/” 主屏幕
  • “/join” join屏幕
  • “/join/djUdmd19m4” 我们要打开的实际屏幕。

这是Flutter开发人员使用常规onGenerateRoute方法最常见的问题。

7.设计:

我很幸运,我也是一个UI/UX设计/开发人员……所以,从技术上说,我是一个

全栈开发人员?!

我查看了一些设计网站,以获得灵感,并知道更多与我的设计,调色板等…我也看了一些开放源码字体使用和废话,废话。

但它们只有一/两个屏幕大小,没有什么新奇之处,没有数据库/业务逻辑,只是一个使用动画的简单而酷的例子。

8.编码:

再说一次,即使我有空闲时间,记住,我有一份全职工作,唯一的空闲时间是我在日常工作之外的时间……但足以让这个新项目迅速完成。

做网站的时候,总有一个大字是“响应”的是的,拜托!记住这个!我们有智能手机、笔记本电脑、台式机、平板电脑等……您的设计应该在每一个屏幕上都是实用/有用的!。

<code>SingleChildScrollView/<code>

是其中一个你会经常使用的小部件,如果你计划有动态列表的话就不是最有用的,因为这个小部件会把所有东西都加载到内存中。

<code>MediaQuery/<code>

为了得到尺寸和方位,超级有用,现在每个人都应该知道,但是…是的。

<code>LayoutBuilder/<code>

太棒了!在考虑不同的形状因素和屏幕时,这一个起到了很好的带头作用。

Screens

我有几个:登录页(主页面),创建页面,加入页面,结果页面,投票页面,关于页面。


你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了


我在屏幕之间移动的整个业务逻辑是通过使用:

<code>Navigator.*of*(context).pushAndRemoveUntil/<code>

我不想为这个产品保留一个堆栈,因为我可以用我的AppBar和屏幕上的一些其他元素/按钮在屏幕之间移动,拜托,它变得对PWA更友好了。

PWA


你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了

是的,flutter支持PWA与否,这两者并不是不同的东西,它们只是两者之间的一个补充。

如果你使用的是Flutter v.1.5+,请确保运行“Flutter create.”来获取丢失的文件。如果由于任何原因您没有它,让我给您以下片段:

在index.html中

<code>/<code>

在您的/web文件夹上,您应该有一个manifest.json文件,如果没有,它如下所示:

<code>{
"name": "App Name",
"short_name": "App Short Name",
"start_url": ".",
"display": "standalone",
"background_color": "#A83EF6",
"theme_color": "#A83EF6",
"description": "App Description",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}/<code>

注意那边的一些元素:

<code>"display": "standalone"/<code>

允许您拥有全屏/本地的外观和感觉。您可以在这里阅读更多信息

你的图标应该在/web/icons(或任何其他文件夹中,但这样看起来不错)中,并且将是你的主屏幕/应用程序抽屉中使用的图标。


你在大公司用Flutter写网页吗?谷歌让你从创意到实现只要2天了

对于我那疯狂又好看的header,我用了:

<code>ClipPath/<code>

使用以下代码段:

<code>class HeaderWaveClipper extends CustomClipper<path> { 
@override
Path getClip(Size size) {
var path = Path();
path.lineTo(0, 0);
path.lineTo(0, size.height - 100);
path.cubicTo(
0,
size.height - 90,
size.width * 0.004,
size.height - 70,
size.width * 0.06,
size.height - 75,
);
path.cubicTo(
size.width * 0.07,
size.height - 75,
size.width * 0.14,
size.height - 95,
size.width * 0.12,
size.height - 65,
);
path.cubicTo(
size.width * 0.12,
size.height - 65,
size.width * 0.08,
size.height - 10,
size.width / 3 * 0.98,
size.height - 40,
);
path.cubicTo(
(size.width / 3) * 1.08,
size.height - 40,
(size.width / 3) - 60,
size.height - 5,
(size.width / 3) + 100,
size.height - 5, );
path.cubicTo(
(size.width / 3) * 1.8,
size.height - 5,

(size.width / 2) * 1.6,
size.height,
(size.width / 2) * 1.52,
size.height - 30, );
path.cubicTo(
(size.width / 2) * 1.52,
size.height - 35,
(size.width / 2) * 1.4,
size.height - 60,
size.width - (size.width * 0.05),
size.height - 60,
);
path.cubicTo(
size.width - (size.width * 0.05),
size.height - 60,
size.width,
size.height - 60,
size.width,
size.height - 90,
);
path.lineTo(size.width, 0);
return path;
}​
@override
bool shouldReclip(CustomClipper<path> oldClipper) => false;}/<path>/<path>/<code>

我花了几个小时来解决这个问题……数学很有趣,但是……是的,花了几个小时让它在每一个屏幕上都反应灵敏,看起来很漂亮。

我说过每件事都花了我大约12个小时的编码,而其中很多时间是在2天的工作框架内进行设计+测试。

在Firebase上托管花了我几秒钟的时间(字面上),而且由于G域的存在,使用我自己的域非常简单。

裂变传播?(希望如此)

我知道有一个特定的网站有我需要的东西来发布我的新创作,那就是Product Hunt - The best new products in tech.

每一个新的/酷的/怪异的产品/项目都结束了,我想知道那是什么感觉!

我想创建我的第一个裂变传播产品后,这么多年的编码没有许多酷/有趣的想法。

这个过程相当直接:

  • 创建帐户
  • 等待1周(或关注他们的时事通讯以获得即时访问)
  • 发布产品
  • 关注每个细节(标题、描述、图标、截图/视频等)
  • 发布!(你可以安排这个)

最后的想法

这真的很有趣,希望人们能经常使用它!我知道这只是一个迷因,但这个有潜力,也许团队会在他们的日历中包含我自动生成的链接,这样每个人都有机会决定会议是否应该是电子邮件。

如果你想了解更多可以点击下面的“了解详情”,嘿嘿


分享到:


相關文章: