flutter初体验
和flutter斗争了两个周末,基本弄清楚了这个玩意的布局和一些常用组件了。
在flutter里面,所有东西都是组件Widget。我们像拼接积木一样拼接Widget,拼接的关键词是child或者children。以我几乎为0的web布局经验,往往在使用widget的时候,头脑里面映射的都是div,table等语义话标签。
StatefulWidget和StatelessWidget
Widget大类上分为两个,StatefulWidget和StatelessWidget。这两个都是抽象类,具体的里面代码我没有进去看。在我理解中,他们两个的区别就是一个是有状态,就是有数据的,在页面切换的时候,需要注意处理这些“状态”,甚至从不同的入口进来是有不同状态的。而另外一个stateless就是无状态,不管什么样子都是这样的一种静态表达。
就我使用的感觉来看,甚至不需要了解太多细节,也能很好使用他们。基本上我们做应用不管是建立应用还是组件,都是使用StatefulWidget。它的基本代码如下:
import 'package:flutter/material.dart';
// 我的页面
class MineView extends StatefulWidget {
MineView({Key key});
@override
State<StatefulWidget> createState() {
return new _MineViewState();
}
}
class _MineViewState extends State<MineView> {
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Text("这是mine");
}
}
每次创建一个StatefulWidget,都需要对应创建一个State。这个State里面的build才是最重要的内容。每次这个StatefulWidget打开的时候都会调用initState方法。貌似这个initState是一些页面打开速度的优化点,里面逻辑要是太多,整个页面效果就很受影响。具体怎么操作后续再学习。
当需要给一个页面传递数据的时候,就需要修改StatefulWidget的构造函数,创建一个类属性,构造函数可以给传递进去。在state里面要获取widget里面的数据的时候直接使用widget.<属性名>就行了。state和widget基本上是联通的。
布局即代码
在flutter中,所有的布局都是代码,用代码来绘制页面上的所有元素。没有了以前安卓的xml等文件。
这种方式让我想起了MVC模式,基本上它把View和Controller混合在一起了。和PHP以前的Smarty时代有的一拼,甚至更为古老。我觉得这种模式其实也没啥太大的问题。作为前端,其实View层远远强大于Controller层,它最好就是做一些展示的工作就好,如果有太多的业务逻辑,反而不美了。所以这种布局即代码应该很多情况下只有View层代码而已,并不会很乱。
其次这种布局即代码的方式大大增加了组件的复用性。组件本质也是开放闭合,代码的方式让一个组件开放的东西更为*了。而且让组件简单的退化为一个包了。(而不是先复制xml,再xxx等)。闭合也更内聚了。最终结果就是复用性大大提高。我要一种很好看的样式,直接import一个包万事。
不过这个让我想到了现在各种语言都颇为混乱的包管理平台。包可以有大,有小,有正规,有垃圾,还有各种升级冲突等问题。可预见的,以后每个flutter developer 也会是每人拥有一个自己最熟悉的军火库了。
布局组件
照着这个项目:https://github.com/pj0579/Flutter_E_Project 撸了一个页面,进行组件学习。说实话,这个项目让我走了不少弯路,感觉作者也是刚写flutter不久。特别是布局方面,我踩了不少坑,不过也慢慢有一些感觉了。下面把遇到的一些组件和注意事项说说:
MaterialApp
这个是风格组件,安卓的Material风格的组件,与之相对应的是Cupertino(IOS风格)。其实这里我也有点困惑,原本我以为的flutter统一Andriod和IOS,我以为是UI也会统一,就是我使用一个控件,在Android下面会是安卓风格,在IOS下面会是IOS风格。不过后来想想,UI层是不可能适配的,毕竟两边的UI风格差别这么大。
MaterialApp基本上最外面的main最外层的一个Widget了
import 'package:flutter/material.dart';
import 'package:first_flutter_app/pages/home_page.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// 第一个widget
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "我的第一个APP",
theme: new ThemeData(
primaryColor: Colors.white,
),
home: MyHomePage()
);
}
}
Scaffold
如果你希望你的页面是上中下分的,上面是一些标题,下面是一些tab按钮,那么不需要你绘制了,这个组件就给你做好了。
它里面有几个属性
- appBar 头部Widget
- body 中间部分的Widget
- bottomNavigationBar 底部的导航按钮设置
基本是必须填写的。
AppBar
这个就是用来填写 Scaffold 的appBar部分。
BottomNavigationBar
这个用来填写 Scaffold 的bottomNavigationBar部分。我基本上用了它的
- items 有哪些按钮
- currentIndex 当前触发的按钮
- onTap 在选择某个按钮的时候触发的动作
这三个属性也就差不多了
Center
这个是偏向布局的属性,表示内部包含的结构在整个父结构的中间
ListView
这个是非常非常重要的组件!!!所有的上下类型的列表结构都可以使用它填充。它有个特点,左右和屏幕一样宽,上下是无限的。
ListView的children属性是保存它展示哪些Widget的。比如:
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
new BannerWidget(
200.0,
this.bannerList,
bannerPress: (pos, item){
print("第 $pos 点击了");
},
),
new LimitWidget(),
new CommonWidget(),
],
);
}
ListView还有一个需要特别注意的地方,就是ListView嵌套的情形,基本上,我们不可能没有ListView嵌套的情形。(当然你的布局分析够牛逼,也是可能的)。当嵌套的时候,需要注意两个属性。
一个是shrinkWrap。被嵌套的必须设置为true。代表我当前的ListView是嵌套在另外一个ListView中的。可能对于当前ListView测绘长宽都是有好处的。
另外一个是physics: new NeverScrollableScrollPhysics(); 这个是为了取消当前ListView的下滑功能。否则你会发现,你触摸在子集ListView的时候滑动的是子的ListView。
当你的ListView的数据比较多,不希望一次性加载完的时候,下拉再渲染的时候,你就要使用ListView.builder来做下拉渲染。
GridView
这个基本上和ListView是齐名的组件,它的表现形式就是网格,在一些商品列表或者卡片列表的时候非常好用。
它也有shrinkWrap和physics属性,也是一样,一旦它被ListView或者GridView嵌套,shrinkWrap需要设置true,physics设置为不允许下拉。
Column 和 Row
这两个也是很经常用,但是我的建议是这两个在最后绘制到具体Widget的时候再用,在大的布局上面还是尽量使用ListView。原因是我碰到了几次使用他们嵌套导致主方向或者从方向长度冲突的问题。(这个真是时间的教训,最开始我使用的都是这两种进行整个页面的布局,后续碰到问题,在这个坑里面绕了一阵,后来使用ListView把外层的全部替换,就过了。)
Column表示它的子元素是一层一层叠加的。Row表示它的子元素是从左到右罗列的。他们都有主方向和次方向,Column的主方向就是上下,Row主方向是左右。主方向和次方向的布局,比如是中间间隔,还是靠左,靠右,还是两边分开。主方向主要看MainAxisAlignment,次方向看CrossAxisAlignment。
Image.network
当从网络获取图片进行展示的时候使用这个组件
Text
文字展示用这个组件
这里就是有个注意点,flutter没有链接的组件,需要去组件库查找,或者自己写。依赖于url_launcher/url_launcher包,大概写法如下:
import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'package:url_launcher/url_launcher.dart';
class Link extends TextSpan {
Link({ TextStyle style, String url, String text }) : super(
style: style,
text: text ?? url,
recognizer: TapGestureRecognizer()
..onTap = () {
launch(url, forceSafariVC: false);
}
);
}
使用
Text.rich(
Link(
style: new TextStyle(fontSize: 12.0,
fontWeight: FontWeight.normal,
color: Colors.blue),
text: "查看全部",
url: "http://baidu.com"
)
)
Card
这个也是很常用的组件。就是带阴影的卡片结构。基本上我现在也就使用到child的属性。
Container
这个就相当于DOM中的div,将内部的结构用Container包裹,统一做一个margin的操作等。
总结
flutter毕竟才1.2,我是很看好它的前景的。(鉴于3年前React刚出来的时候我也做过类似判断,这句话听听就算了。)我的观点就是市场决定语言的普世程度。后续开发APP会变得异常简单(当然基于对UI要求不是那么严格的情况下)。毕竟能一份代码同时开发IOS和Android,甚至以后的桌面应用和Web应用,简直把天堂描述的太美好了。
然后这个语言的大公司支持程度也很牛,Google,国内的阿里(闲鱼)。加了闲鱼的一个群,一天之内成员就达到上线。。。目测一大波程序员已经涌入了,可是这个是在革自己的命啊。。。感叹下,但是对大局来说,把开发成本降最低绝对是一个好事。
flutter初体验的更多相关文章
-
Flutter初体验--环境搭建
Fluter最近火了起来,它的有点很多,今天我做一篇在Windows下安装Flutter的教程. 一.下载 无论你要安装什么软件,都要先下载下来.我用的是SourceTree,地址: https ...
-
.NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...
-
Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验
Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...
-
Spring之初体验
Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...
-
Xamarin.iOS开发初体验
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0
-
【腾讯Bugly干货分享】基于 Webpack &; Vue &; Vue-Router 的 SPA 初体验
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...
-
【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
-
在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验
在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...
-
百度EChart3初体验
由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...
随机推荐
-
用SignalR 2.0开发客服系统[系列2:实现聊天室]
前言 交流群:195866844 上周发表了 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 这篇文章,得到了很多帮助和鼓励,小弟在此真心的感谢大家的支持.. 这周继续系列2,实现聊天室 ...
-
jQuery/js 正则收集(邮件验证、)
var reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/; //验证邮箱的正则表达式if( ...
-
2015最新移动App设计尺寸视觉规范【图文版】(转)
如今手机app的屏幕设计尺寸参差不齐,仿佛来到了移动界面尺寸战国时代,每家移动设备制造公司都为了迎合大众的口味,各家都在2014年大放光彩.2015年也将会是我们移动APP设计界快速发展的一年. 因为 ...
-
DES根据键值加密解密
import java.io.IOException; import java.net.URLEncoder; import java.security.SecureRandom; import ja ...
-
linux日志处理logrotate使用
摘录自:http://linux008.blog.51cto.com/2837805/555829 内容在这里做个备份,以便以后查看: 使用logrotate管理nginx日志文件 2011-04- ...
-
ubuntu12.04和deepin12.06使用root账户登录
修改lightdm.conf登录方式, 1.首先,激活root账户, 在终端中执行 sudo passwd root 连续两次输入 密码,即使root账户的密码,注意密码并不在终端中显示 2. 切 ...
-
JAVA面试题:69道Spring面试题和答案
目录 Spring 概述 依赖注入 Spring beans Spring注解 Spring数据访问 Spring面向切面编程(AOP) Spring MVC Spring 概述 1. 什么是spri ...
-
javaScript中的return,break,continue的区别
导语: javaScript中有三种方法可以跳出循环或者终止循环.分别为break.return.continue. 正文: 一.break break 会使得整个程序终止执行或者包含了最内层的循环或 ...
-
BZOJ_1085_[SCOI2005]骑士精神_IDDFS
BZOJ_1085_[SCOI2005]骑士精神_DFS Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可 ...
-
Office Web Apps 2013 修改Excel在线查看文件大小限制
前言 最近搭建了一个OWA 2013环境,帮客户实现在线查看Excel文档,不过,使用过程中出现了错误,文件大小超过10MB就无法预览了,查了好久,发现需要使用PowerShell命令进行修改. 1. ...