原文:blog.cyning.cc/2019/05/12/…
Flutter已经出了稳定版,这对于很对开发者来说,终于可以长长吐一口气了,我也来踩坑啦。
什么是Flutter
Flutter究竟是个啥,他对于开发者有什么益处,学习它有什么准备课程么? 针对这个问题,或许在开始写代码前,你要思考下?
混合开发
曾经接触过用webview
和JSbridege
的混合开发,也曾经在经历过React Native
,总体来说,混合开发的体验不好,而RN对于之前的版本适配和复杂UI加载通讯总是让人觉得比原生差太多,Flutter试了下,除了包大了点点,可以完美避免这写问题,不过是骡子是马,我们都要先溜一圈。
Flutter还支持了Web,感觉Google大哥有点膨胀啊,你这是要统治全端么,不过说实话Dart这种语言最初也是给前端开发使用的。
dart
对于Flutter,我们需要了解dart的语法,不过不要死记硬背,没啥意思,感觉会js或者java足够了你能看懂,慢慢模仿就行了 我们这里简单介绍下dart吧,避免不必要的麻烦。
包引入
dart的一个个库,也是用dart写的,未来有一天你的库也可以被更多人的使用。 只需要项引入java一样或者类似react js的引入其他包:
import 'package:http/http.dart';
变量
dart也是给一个强类型语言,定义变量可以不用写明类型。
私有变量
对于私有变量,它不像java
语言有privte这种access flag,所以要在命令上规范未下划线开始。
String _firstName;
私有方法
static _parsePirateNamesFromJSON(String jsonString) {
Map pirateNames = JSON.decode(jsonString);
names = pirateNames['names'];
appellations = pirateNames['appellations'];
}
类型转换
void updateBadge(Event e) {
String inputName = (e.target as InputElement).value;
}
方法
有些方法可以直接使用表达式的值即为返回值的情况
String toString() => pirateName;
和之前的写法说再见吧:
String toString() {
return pirateName;
}
级联操作符(..)
记得之前特别喜欢用链式的结构,现在你需要的来了,多个函数操作,用级联操作符:
genButton..disabled = false
..text = 'Aye! Gimme a name!';
这就相当于:
genButton.disabled = false;
genButton.text = 'Aye! Gimme a name!';
变量可以加到字符串中
这个在shell和python中不是什么新鲜玩意,只需要加个$符号(见到美刀,就可以替换,也是给个钱迷啊)
String _firstName = "cyning"
print '$_firstName the $_appellation';
参数
和其他解释性语言一样,支持参数可选
Getters and setters
getter 和setter 是 Dart 中特殊的函数,看起来像是变量。可以像下面这样来重新定义 Spacecraft 类的 launchYear 属性:
class Spacecraft {
// ...
DateTime launchDate;
int get launchYear => launchDate?.year;
// ...
}
继承
Dart 是单继承的。
class Orbiter extends Spacecraft {
num altitude;
Orbiter(String name, DateTime launchDate, this.altitude)
: super(name, launchDate);
}
异步操作
Dart 语言原生支持异步操作,主要是用两个关键词 await 和 async。
在函数上加async
,不需要像 java 那样去 new Thread,在用到耗时的地方加上await。
// 发起网络请求
loadData() async{
String requestURL = 'http://gank.io/api/today';
Client client = Client();
Response response = await client.get(requestURL);
String jsonString = response.body;
print(jsonString);
}
第一个demo
至于环境搭建,可以参考Flutter中文网来一步步搭建,我使用的编辑器是Vs code
新建
为了能验证是否生效,来跑下,还是这图上图,使用starting debug
运行,手机或者虚拟机尽量连着开发机。
注意事项
同步库时,需要将jcenter库,替换为阿里的镜像:
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
}
}
allprojects {
repositories {
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
}
项目结构
目前demo的目录结构如下,其中android
文件下是一个正常的android程序。
| |____android
| |____ios
| |____lib
| | |____main.dart
| |___pubspec.yaml
lib下有个main.dart,这个就是我们需要操作的dart文佳。
pubspec.yaml是配置的相关。
hello world跑起来
可以修改lib/main.dart如下代码:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
// 主题
theme: ThemeData(
primarySwatch: Colors.blue,
),
// 首页的页面
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
child: new Text('Hello World'),
),
),
);
}
}
p跑起来截图:
-
main函数使用了(=>)符号, 这是Dart中单行函数或方法的简写
-
Scaffold 是 Material library 中提供的一个widget, 它提供了默认的导航栏、标题和包含主屏幕widget树的body属性。widget树可以很复杂。
-
MyApp继承自StatelessWidget, Statelesswidgets是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的.
添加一个 有状态的部件(Stateful widget)
我们需要替换MaterialApp下22行的child: new Text('Hello World')
属性为一个StatefulWidget
。
而Stateful widgets 持有的状态可能在widget生命周期中发生变化. 实现一个 stateful widget 至少需要两个类:
一个StatefulWidget
类。
一个 State
类。
StatefulWidget类本身是不变的,但是
State类`在widget生命周期中始终存在.
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Text("hello MyHomePage");
}
}
当然了也可以使用过动态设置_MyHomePageState为其他文本,如一个单词,这就需要引入english_words
库。
在项目的根路径下找到lpubspec.yaml
,添加:
import 'package:english_words/english_words.dart';
只需要在MyHomePage的build方法里修改代码如下:
final wordPair = new WordPair.random();
return Text(wordPair.asPascalCase);
这样每次启动都会触发页面刷新,都会随机出现一个单词。
交互
我们还需要未这个添加一个交互,例如当我们点击时,就可以换一个单词,将Text替换可以点击的RaisedButton
:
final wordPair = new WordPair.random();
return RaisedButton(
child: Text(wordPair.asPascalCase),
onPressed: clickbtn,
);
好了这代码基本是否让我们对StatefulWidget
的理解呢?