鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼
Posted 鍥鹃泙绀惧尯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼相关的知识,希望对你有一定的参考价值。
w鏈枃鐢卞浘闆€绀惧尯璁よ瘉浣滆€?nbsp;Tyler 鍐欎綔鑰屾垚锛岋紝鐐瑰嚮闃呰鍘熸枃鏌ョ湅浣滆€呯殑鍗氬閾炬帴锛屾劅璋綔鑰呯殑浼樿川杈撳嚭锛岃鎴戜滑鐨勬妧鏈笘鐣屽彉寰楁洿鍔犵編濂金煒?/p>
娑夊強Dart璇█锛孎lutter鍘熺悊锛孎lutter Widget锛屼互鍙奆lutter涓殑鐘舵€佺鐞嗘柟妗堢瓑锛屽牚绉版渶鍏ㄧ殑Flutter鏁欑▼馃槃
鏈€鐖辨姌鑵剧殑灏辨槸鍓嶇宸ョ▼甯堜簡锛屼粠 jQuery 鎶樿吘鍒?AngularJs锛屽啀鎶樿吘鍒?Vue銆丷eact銆傛渶鐖辫法绔殑涔熸槸鍓嶇宸ョ▼甯堬紝浠?phonegap锛屾姌鑵惧埌 React Native锛岃繖涓嶅張鎶樿吘鍒颁簡 Flutter銆傚浘鍟ワ紵浣庢垚鏈?/strong>鍦颁负鐢ㄦ埛甯︽潵鏇翠紭绉€鐨勭敤鎴蜂綋楠?/strong>銆傜洰鍓嶆潵璇?span class="mq-10">Flutter[1]鍙兘鏄叾涓渶浼樼鐨勪竴绉嶆柟妗堜簡銆?/p>
Flutter is Google鈥檚 UI toolkit for building beautiful, natively compiled applications for mobile[2], web[3], and desktop[4] from a single codebase. Flutter[5]鏄敱鍘?Google Chrome 鍥㈤槦鎴愬憳锛屽埄鐢?Chrome 2D 娓叉煋寮曟搸锛岀劧鍚庣簿绠€ CSS 甯冨眬婕斿彉鑰屾潵銆?img data-ratio="0.517774343122102" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsicX5icbrzT629hF3WkickcTibtn5FOtNxsVPmHw5qwgrgyFBeZ1kUZxicp2A/640?wx_fmt=png" data-type="png" data-w="1294" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-25">鎴栬€呮洿璇︾粏鐨勭増鏈?img data-ratio="0.5247469066366705" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsicqr1Xpn9qOrFSY7po1MuGcwiamZ5HzxpbMMQxF9ZlgsmnRkia47D9PShA/640?wx_fmt=png" data-type="png" data-w="3556" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-26"> 浠庢灦鏋勪腑瀹為檯涓婂凡缁忚兘鐪嬪嚭 Flutter 涓轰粈涔堝揩锛岃嚦灏戠浉姣斾箣鍓嶇殑褰撶孩鐐稿瓙楦?React Native 蹇殑鍘熷洜浜嗐€?/p>
鑰岀浉姣?React Native锛?/p>
鑰屽叿浣撲袱鑰呯殑鎬ц兘娴嬭瘯锛屽彲浠ョ湅杩欓噷[6]锛岀粨璁烘槸 Flutter锛屽湪 CPU锛孎PS锛屽唴瀛樼ǔ瀹氫笂鍧囦紭浜?ReactNative銆?/p>
鍦ㄥ紑濮?Flutter 涔嬪墠锛屾垜浠渶瑕佸厛浜嗚В涓?Dart 璇█鈥︹€?Dart 鏄敱 Google 寮€鍙戯紝鏈€鍒濇槸鎯充綔涓?JavaScript 鏇夸唬璇█锛屼絾鏄け璐ユ矇瀵備箣鍚庯紝浣滀负 Flutter 鐙湁寮€鍙戣瑷€鍙堢剷鍙戜簡绗簩鏄?馃槀銆傚疄闄呬笂鍗充娇鍒颁簡 2.0锛?span class="mq-50">Dart 璇硶Flutter 鏄粈涔堬紵
Flutter 涓轰粈涔堝揩锛烣lutter 鐩告瘮 RN 鐨勪紭鍔垮湪鍝噷锛?/h2>
Dart 璇█
-
涓嶄細椋樼殑 this
-
寮虹被鍨嬶紝褰撶劧鍓嶇鐜板湪鏈変簡 TypeScript 馃槵 -
寮哄ぇ鏂逛究鐨勬搷浣滅鍙凤細 -
?.
鏂逛究瀹夊叏鐨?foo?.bar
鍙栧€硷紝濡傛灉 foo 涓?null
锛岄偅涔堝彇鍊间负null
-
??
condition ? expr1 : expr2
鍙互绠€鍐欎负expr1 ?? expr2
-
=
鍜屽叾浠栫鍙风殑缁勫悎:*=
銆?~/=
銆?&=
銆?|=
鈥︹€? -
绾ц仈鎿嶄綔绗?Cascade notation ..)
// 鎯虫兂杩欐牱鐪佷簡澶氬皯鍙橀噺澹版槑
querySelect('#button')
..text ="Confirm"
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed'))
鐢氳嚦鍙互閲嶅啓鎿嶄綔绗?/p>
class Vector {
final int x, y;
Vector(this.x, this.y);
Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
// Operator == and hashCode not shown. For details, see note below.
// 路路路
}
void main() {
final v = Vector(2, 3);
final w = Vector(2, 2);
assert(v + w == Vector(4, 5));
assert(v - w == Vector(0, 1));
}
娉細閲嶅啓==
锛屼篃闇€瑕侀噸鍐?Object hashCode
getter
class Person {
final String firstName, lastName;
Person(this.firstName, this.lastName);
// Override hashCode using strategy from Effective Java,
// Chapter 11.
@override
int get hashCode {
int result = 17;
result = 37 * result + firstName.hashCode;
result = 37 * result + lastName.hashCode;
return result;
}
// You should generally implement operator == if you
// override hashCode.
@override
bool operator ==(dynamic other) {
if (other is! Person) return false;
Person person = other;
return (person.firstName == firstName &&
person.lastName == lastName);
}
}
void main() {
var p1 = Person('Bob', 'Smith');
var p2 = Person('Bob', 'Smith');
var p3 = 'not a person';
assert(p1.hashCode == p2.hashCode);
assert(p1 == p2);
assert(p1 != p3);
}
杩欑偣鍦?diff 瀵硅薄鐨勬椂鍊欏挨鍏舵湁鐢ㄣ€?/p>
lsolate
Dart 杩愯鍦ㄧ嫭绔嬮殧绂荤殑 iSolate 涓氨绫讳技 JavaScript 涓€鏍凤紝鍗曠嚎绋嬩簨浠堕┍鍔紝浣嗘槸 Dart 涔熷紑鏀句簡鍒涘缓鍏朵粬 isolate锛屽厖鍒嗗埄鐢?CPU 鐨勫鍜岃兘鍔涖€?/p>
loadData() async {
// 閫氳繃spawn鏂板缓涓€涓猧solate锛屽苟缁戝畾闈欐€佹柟娉?/span>
ReceivePort receivePort =ReceivePort();
await Isolate.spawn(dataLoader, receivePort.sendPort);
// 鑾峰彇鏂癷solate鐨勭洃鍚琾ort
SendPort sendPort = await receivePort.first;
// 璋冪敤sendReceive鑷畾涔夋柟娉?/span>
List dataList = await sendReceive(sendPort, 'https://hicc.me/posts');
print('dataList $dataList');
}
// isolate鐨勭粦瀹氭柟娉?/span>
static dataLoader(SendPort sendPort) async{
// 鍒涘缓鐩戝惉port锛屽苟灏唖endPort浼犵粰澶栫晫鐢ㄦ潵璋冪敤
ReceivePort receivePort =ReceivePort();
sendPort.send(receivePort.sendPort);
// 鐩戝惉澶栫晫璋冪敤
await for (var msg in receivePort) {
String requestURL =msg[0];
SendPort callbackPort =msg[1];
Client client = Client();
Response response = await client.get(requestURL);
List dataList = json.decode(response.body);
// 鍥炶皟杩斿洖鍊肩粰璋冪敤鑰?/span>
callbackPort.send(dataList);
}
}
// 鍒涘缓鑷繁鐨勭洃鍚琾ort锛屽苟涓斿悜鏂癷solate鍙戦€佹秷鎭?/span>
Future sendReceive(SendPort sendPort, String url) {
ReceivePort receivePort =ReceivePort();
sendPort.send([url, receivePort.sendPort]);
// 鎺ユ敹鍒拌繑鍥炲€硷紝杩斿洖缁欒皟鐢ㄨ€?/span>
return receivePort.first;
}
褰撶劧 Flutter 涓皝瑁呬簡compute[9]锛屽彲浠ユ柟渚跨殑浣跨敤锛岃濡?span class="mq-203">鍦ㄥ叾瀹?isolate 涓В鏋愬ぇ鐨?json[10]銆?/p>
Dart UI as Code
鍦ㄨ繖閲屽崟鐙彁鍑烘潵鐨勬剰涔夊湪浜庯紝浠?React 寮€濮嬶紝鍒?Flutter锛屽埌鏈€杩戠殑 Apple SwiftUI锛孉ndroid Jetpack Compose 澹版槑寮忕粍浠跺啓娉曡秺鍙戞祦琛岋紝Web 鍓嶇浣跨敤 JSX 鏉ヨ寮€鍙戣€呮洿鏂逛究鐨勪功鍐欙紝鑰?Flutter锛孲wiftUI 鍒欑洿鎺ヤ粠浼樺寲璇█鏈韩鐫€鎵嬨€?/p>
鍑芥暟绫荤殑鍛藉悕鍙傛暟
void test({@required int age,String name}) {
print(name);
print(age);
}
// 瑙e喅鍑芥暟璋冪敤鏃跺€欙紝鍙傛暟涓嶆槑纭殑闂
test(name:"hicc",age: 30)
// 杩欐牱瀵逛簬缁勪欢鐨勪娇鐢ㄥ挨涓烘柟渚?/span>
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(),
floatingActionButton:FloatingActionButton()
);
}
}
澶ф潃鍣細Collection If 鍜?Collection For
// collection If
Widget build(BuildContext context) {
return Row(
children: [
IconButton(icon: Icon(Icons.menu)),
Expanded(child: title),
if (!isandroid)
IconButton(icon: Icon(Icons.search)),
],
);
}
// Collect For
var command = [
engineDartPath,
frontendServer,
for (var root in fileSystemRoots) "--filesystem-root=$root",
for (var entryPoint in entryPoints)
if (fileExists("lib/$entryPoint.json")) "lib/$entryPoint",
mainPath
];
鏇村 Dart 2.3 瀵规鐨勪紭鍖栫湅杩欓噷[11]銆?/p>
Flutter 鎬庝箞鍐?/h2>
鍒拌繖閲岀粓浜庡埌姝i浜嗭紝濡傛灉鐔熸倝 web 鍓嶇锛岀啛鎮?React 鐨勮瘽锛屼綘浼氬涓嬮潰瑕佽鐨勫紓甯哥殑鐔熸倝銆?img data-ratio="0.36220472440944884" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsicRWFvfSiauXEibdfU3Nias4HGktTiayrVuzMlEd6Po83GutC7qjBtC2VAlg/640?wx_fmt=png" data-type="png" data-w="762" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-265">Flutter App 鐨勪竴鍒囦粠lib/main.dart
鏂囦欢鐨?main 鍑芥暟寮€濮嬶細
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Hello World'),
),
),
);
}
}
Dart 绫?build 鏂规硶杩斿洖鐨勪究鏄?Widget锛屽湪 Flutter 涓竴鍒囬兘鏄?Widget锛屽寘鎷絾涓嶉檺浜?/p>
-
缁撴瀯鎬у厓绱狅紝menu锛宐utton 绛? -
鏍峰紡绫诲厓绱狅紝font锛宑olor 绛? -
甯冨眬绫诲厓绱狅紝padding锛宮argin 绛? -
瀵艰埅 -
鎵嬪娍
Widget 鏄?Dart 涓壒娈婄殑绫伙紝閫氳繃瀹炰緥鍖?Dart 涓?span class="mq-291">new 鏄彲閫夌殑[12])鐩镐簰宓屽锛屼綘鐨勮繖涓?App 灏辨槸褰㈠涓嬪浘鐨勪竴棰楃粍浠舵爲(Dart 鍏ュ彛鍑芥暟鐨勬蹇碉紝main.dart -> main()
)銆?img data-ratio="0.5609492988133765" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsic9oYORrfTdx6qCmy2PxIqEDofjAJIfhsox1kgrz5TCqYD190ehRxRZQ/640?wx_fmt=png" data-type="png" data-w="1854" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-294">
Widget 甯冨眬
涓婅杩?Flutter 甯冨眬鎬濊矾鏉ヨ嚜 CSS锛岃€?Flutter 涓竴鍒囩殕 Widget锛屽洜姝ゆ暣浣撳竷灞€涔熷緢绠€鍗曪細
-
瀹瑰櫒缁勪欢 Container -
decoration 瑁呴グ灞炴€э紝璁剧疆鑳屾櫙鑹诧紝鑳屾櫙鍥撅紝杈规锛屽渾瑙掞紝闃村奖鍜屾笎鍙樼瓑 -
margin -
padding -
alignment -
width -
height -
Padding锛孋enter -
Row,Column,Flex -
Wrap, Flow 娴佸紡甯冨眬 -
Stack锛?z 杞村竷灞€ -
鈥︹€?
鏇村鍙互鐪嬭繖閲?/span>[13]Flutter 涓?Widget 鍙互鍒嗕负涓夌被锛屽舰濡?React 涓€滃睍绀虹粍浠垛€濄€佲€滃鍣ㄧ粍浠垛€濓紝鈥渃ontext鈥濄€?/p>
杩欎釜灏辨槸 Flutter 涓殑鈥滃睍绀虹粍浠垛€濓紝鑷韩涓嶄繚瀛樼姸鎬侊紝澶栭儴鍙傛暟鍙樺寲灏遍攢姣侀噸鏂板垱寤恒€侳lutter 寤鸿灏介噺浣跨敤鏃犵姸鎬佺殑缁勪欢銆?/p>
鐘舵€佺粍浠跺氨鏄被浼间簬 React 涓殑鈥滃鍣ㄧ粍浠垛€濅簡锛孎lutter 涓姸鎬佺粍浠跺啓娉曚細绋嶅井涓嶄竴鏍枫€?/p>
鍙互鐪嬪埌 Flutter 涓洿鎺ヤ娇鐢ㄤ簡鍜?React 涓悓鍚嶇殑StatelessWidget
StatefulWidget
class Counter extends StatefulWidget {
// This class is the configuration for the state. It holds the
// values (in this case nothing) provided by the parent and used by the build
// method of the State. Fields in a Widget subclass are always marked "final".
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _counter = 0;
void _increment() {
setState(() {
// This call to setState tells the Flutter framework that
// something has changed in this State, which causes it to rerun
// the build method below so that the display can reflect the
// updated values. If you change _counter without calling
// setState(), then the build method won't be called again,
// and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance
// as done by the _increment method above.
// The Flutter framework has been optimized to make rerunning
// build methods fast, so that you can just rebuild anything that
// needs updating rather than having to individually change
// instances of widgets.
return Row(
children: <Widget>[
RaisedButton(
onPressed: _increment,
child: Text('Increment'),
),
Text('Count: $_counter'),
],
);
}
}setState
鏂规硶锛屼笉杩囦笉浼氭湁鍙橀噺鍚堝苟鐨勪笢瑗匡紝褰撶劧涔熸湁鐢熷懡鍛ㄦ湡[14]銆?img data-ratio="1.4268537074148298" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsicKoLkLIX38vOcI5FWfOI3nOBfxJLMqP7KfuYHoRnJFWibLeMvRH6fP6A/640?wx_fmt=png" data-type="png" data-w="499" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-366">鍙互鐪嬪埌涓€涓湁鐘舵€佺殑缁勪欢闇€瑕佷袱涓?Class锛岃繖鏍峰啓鐨勫師鍥犲湪浜庯紝Flutter 涓?Widget 閮芥槸 immmutable 鐨勶紝鐘舵€佺粍浠剁殑鐘舵€佷繚瀛樺湪 State 涓紝缁勪欢浠嶇劧姣忔閲嶆柊鍒涘缓锛學idget 鍦ㄨ繖閲屽彧鏄竴绉嶅缁勪欢鐨勬弿杩帮紝Flutter 浼?diff 杞崲鎴?Element锛岀劧鍚庤浆鎹㈡垚 RenderObject 鎵嶆覆鏌撱€?img data-ratio="0.5806451612903226" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsicU4gPx6XpFbvzf5CUMPaGjweKYdTOR76N6RylMicxhGRUiaI7D4HELTfg/640?wx_fmt=png" data-type="png" data-w="2108" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-367">Flutter Widget 鏇村鐨勬覆鏌撴祦绋嬪彲浠ョ湅杩欓噷[15]銆傚疄闄呬笂 Widget 鍙槸浣滀负缁勪欢缁撴瀯涓€绉嶆弿杩帮紝杩樺彲浠ュ甫鏉ョ殑濂藉鏄紝浣犲彲浠ユ洿鏂逛究鐨勫仛涓€浜?span class="mq-370">涓婚鎬х殑缁勪欢
State Management
setState()
鍙互寰堟柟渚跨殑绠$悊缁勪欢鍐呯殑鏁版嵁锛屼絾鏄?Flutter 涓姸鎬佸悓鏍锋槸浠庝笂寰€涓嬫祦杞殑锛屽洜姝や篃浼氶亣鍒板拰 React 涓悓鏍风殑闂锛屽鏋滅粍浠舵爲澶繁锛岄€愬眰鐘舵€佸垱寤哄氨鏄惧緱寰堥夯鐑︿簡锛屾洿涓嶈璇翠唬鐮佺殑鏄撹鍜屾槗缁存姢鎬т簡銆?/p>
InheritedWidget
鍚屾牱 Flutter 涔熸湁涓?code class="mq-387">context涓€鏍风殑涓滆タ锛岄偅灏辨槸InheritedWidget
锛屼娇鐢ㄨ捣鏉ヤ篃寰堢畝鍗曘€?/p>
class GlobalData extends InheritedWidget {
final int count;
GlobalData({Key key, this.count,Widget child}):super(key:key,child:child);
@override
bool updateShouldNotify(GlobalData oldWidget) {
return oldWidget.count != count;
}
static GlobalData of(BuildContext context) => context.inheritFromWidgetOfExactType(GlobalData);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GlobalData(
count: _counter,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
Body(),
Body2()
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
GlobalData globalData = GlobalData.of(context);
return Text(globalData.count.toString());
}
}
class Body2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
GlobalData globalData = GlobalData.of(context);
return Text(globalData.count.toString());
}
鍏蜂綋瀹炵幇鍘熺悊鍙互鍙傝€?span class="mq-457">杩欓噷[20]锛屼笉杩?Google 灏佽浜嗕竴涓洿涓轰笂灞傜殑搴?span class="mq-459">provider[21]锛屽叿浣撲娇鐢ㄥ彲浠ョ湅杩欓噷[22]銆?/p>
BlOC
BlOC[23]鏄?Flutter team 鎻愬嚭寤鸿鐨勫彟涓€绉嶆洿楂樼骇鐨勬暟鎹粍缁囨柟寮忥紝涔熸槸鎴戞渶涓剰鐨勬柟寮忋€傜畝鍗曟潵璇达細Bloc = InheritedWidget + RxDart(Stream)Dart 璇█涓唴缃簡 Steam锛孲tream ~= Observable锛岄厤鍚?span class="mq-470">RxDart[24], 鐒跺悗鍔犱笂StreamBuilder
浼氭槸涓€绉嶅紓甯稿己澶у拰鑷敱鐨勬ā寮忋€?/p>
class GlobalData extends InheritedWidget {
final int count;
final Stream<String> timeInterval$ = new Stream.periodic(Duration(seconds: 10)).map((time) => new DateTime.now().toString());
GlobalData({Key key, this.count,Widget child}):super(key:key,child:child);
@override
bool updateShouldNotify(GlobalData oldWidget) {
return oldWidget.count != count;
}
static GlobalData of(BuildContext context) => context.inheritFromWidgetOfExactType(GlobalData);
}
class TimerView extends StatelessWidget {
@override
Widget build(BuildContext context) {
GlobalData globalData = GlobalData.of(context);
return StreamBuilder(
stream: globalData.timeInterval$,
builder: (context, snapshot) {
return Text(snapshot?.data ?? '');
}
);
}
}
褰撶劧 Bloc 鐨勯棶棰樺湪浜?/p>
-
瀛︿範鎴愭湰鐣ラ珮锛孯x 鐨勬蹇佃鍚冮€忥紝涓嶇劧浣犱細鎶撶媯 -
鑷敱甯︽潵鐨勯棶棰樻槸锛屽彲鑳戒唬鐮佷笉濡?Redux 绫荤殑瑙勬暣銆?
椤轰究锛屼粖骞?Apple 涔熸嫢鎶变簡鍝嶅簲寮忥紝Combine[25](Rx like) + SwiftUI 涔熷熀鏈瓑浜?Bloc 浜嗐€傛墍浠ワ紝Rx 杩樻槸瑕佽刀绱у璧锋潵 馃槵 闄ゅ幓 Bloc锛孎lutter 涓繕鏄彲浠ヤ娇鐢ㄥ叾浠栫殑鏂规锛岃濡傦細
-
Flutter Redux [26] -
闃块噷闂查奔鐨? Fish Redux [27]锛? 鎹鎬ц兘寰堝ソ銆? -
Mobx [28] -
鈥︹€?
灞曞紑鏉ヨ鐜板湪鐨勫墠绔紑鍙戜娇鐢ㄥ己澶х殑妗嗘灦椤甸潰缁勮宸茬粡涓嶆槸闅剧偣浜嗐€傚紑鍙戠殑闅剧偣鍦ㄤ簬濡備綍缁勫悎瀵屼氦浜掓墍闇€鐨勬暟鎹紝涔熷氨鏄笂闈㈠浘涓殑state
閮ㄥ垎銆傛洿鍏蜂綋鏉ヨ锛屾槸鎬庝箞浼橀泤锛岄珮鏁堬紝鏄撶淮鎶ゅ湴澶勭悊鐭殏鏁版嵁(ephemeral state)setState()
鍜岄渶瑕佸叡浜殑 App State 鐨勯棶棰橈紝杩欐槸涓伐绋嬫€х殑闂锛屼絾寰€寰€涔熸槸鏃ュ父寮€鍙戞渶闅剧殑浜嬫儏浜嗭紝寮曠敤 Redux 浣滆€?Dan 鐨勪竴鍙ワ細
鈥淭he rule of thumb is:Do whatever is less awkward[29].鈥?/p>
鍒拌繖閲岋紝涓昏鐨勯儴鍒嗗凡缁忚瀹屼簡锛屾湁杩欎簺宸茬粡鍙互寮€鍙戝嚭涓€涓笉閿欑殑 App 浜嗐€傚墿涓嬬殑灏卞綋鎴愪竴涓?bonus 鍚с€?/p>
娴嬭瘯
Flutter debugger锛屾祴璇曢兘鏄嚭鍦鸿嚜甯︼紝鐢ㄨ捣鏉ヤ篃涓嶉毦銆?/p>
// 娴嬭瘯鍦?test/鐩綍涓嬮潰
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
鍖呯鐞嗭紝璧勬簮绠$悊
绫讳技涓?JavaScript 鐨?npm锛孎lutter锛屼篃灏辨槸 Dart 涔熸湁鑷繁鐨?span class="mq-557">鍖呬粨搴?/span>[30]銆備笉杩囬」鐩寘鐨勪緷璧栦娇鐢?yaml 鏂囦欢鏉ユ弿杩?
name: app
description: A new Flutter project.
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
鐢熷懡鍛ㄦ湡
绉诲姩搴旂敤鎬诲綊闇€瑕佸簲鐢ㄧ骇鍒殑鐢熷懡鍛ㄦ湡锛宖lutter 涓娇鐢ㄧ敓鍛藉懆鏈熼挬瀛愶紝涔熼潪甯哥殑绠€鍗曪細
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.inactive:
print('AppLifecycleState.inactive');
break;
case AppLifecycleState.paused:
print('AppLifecycleState.paused');
break;
case AppLifecycleState.resumed:
print('AppLifecycleState.resumed');
break;
case AppLifecycleState.suspending:
print('AppLifecycleState.suspending');
break;
}
super.didChangeAppLifecycleState(state);
}
@override
Widget build(BuildContext context) {
return Container();
}
}
浣跨敤鍘熺敓鑳藉姏
鍜?ReactNative 绫讳技锛孎lutter 涔熸槸浣跨敤绫讳技浜嬩欢鐨勬満鍒舵潵浣跨敤骞冲彴鐩稿叧鑳藉姏銆?img data-ratio="1.1155172413793104" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsic6yibAGrTMlz0GpnTDQicZjy233bkghO1TY6HC1c70fyk0iaQymEaN0ic2w/640?wx_fmt=png" data-type="png" data-w="580" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-623">
Flutter Web, Flutter Desktop
杩欎簺杩樺湪寮€鍙戝綋涓紝閴翠簬瀵?Dart 鍠滄锛屼互鍙婂 Flutter 鎬ц兘鐨勪箰瑙傦紝杩欎簺鍊掓槸寰堝€煎緱鏈熷緟銆?img data-ratio="0.40897097625329815" src="/img?url=https://mmbiz.qpic.cn/mmbiz_png/gEz4yUa4ueSV30picZ75OH9icA4920FUsicLjKxMfdO141Uib7SGVHBJhNOcibcmxBGBLSHG4nn4YBsdCl0A90cwngw/640?wx_fmt=png" data-type="png" data-w="1137" alt="鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼" class="mq-627">杩樿寰楀钩鍙板彧鏄粰 Flutter 鎻愪緵涓€涓敾甯冧箞锛孎lutter Desktop 鏈潵鏇存槸鍙互澶ф湁鍙负 馃槃锛岀浉鍏冲彲浠ョ湅杩欓噷[31]銆傛渶鍚庢瘡绉嶆柟妗堬紝姣忕鎶€鏈兘鏈?span class="mq-630">浼樼己鐐?/span>[32]锛岀敋鑷虫妧鏈殑鏋舵瀯鍐冲畾浜嗭紝鏈変簺缂洪櫡鍙兘姘歌繙閮芥病娉曟敼杩涳紝鎵€浠?馃
鏈€鍚庣殑鏈€鍚庯紝寮虹儓鎺ㄨ崘闂查奔鍥㈤槦鐨?span class="mq-634">Flutter Blog[33]馃憤锛屽父甯告嫓璇伙紝鏀剁泭鑹
鍙傝€冭祫鏂?/span>
Flutter: https://flutter.dev/
[2]mobile: https://flutter.dev/docs
[3]web: https://flutter.dev/web
[4]desktop: https://flutter.dev/desktop
[5]Flutter: https://flutter.dev/
[6]杩欓噷: https://www.yuque.com/xytech/flutter/gs3pnk
[7]Dart 璇硶: https://dart.dev/guides/language/language-tour
[8]Flutter: https://flutter.dev/
[9]compute: https://api.flutter.dev/flutter/foundation/compute.html
[10]鍦ㄥ叾瀹?isolate 涓В鏋愬ぇ鐨?json: https://flutter.dev/docs/cookbook/networking/background-parsing
[11]杩欓噷: https://medium.com/dartlang/making-dart-a-better-language-for-ui-f1ccaf9f546c
[12]new 鏄彲閫夌殑: https://dart.dev/guides/language/language-tour#using-constructors
[13]鏇村鍙互鐪嬭繖閲? https://www.yuque.com/xytech/flutter/hc0xq7
[14]鐢熷懡鍛ㄦ湡: https://segmentfault.com/a/1190000015211309
[15]杩欓噷: https://www.yuque.com/xytech/flutter/tge705
[16]涓婚鎬х殑缁勪欢: https://flutter.dev/docs/development/ui/widgets
[17]Material Components widgets: https://flutter.dev/docs/development/ui/widgets/material
[18]Cupertino (iOS-style) widgets: https://flutter.dev/docs/development/ui/widgets/cupertino
[19]Hot Reload: https://flutter.dev/docs/development/tools/hot-reload
[20]杩欓噷: https://loveky.github.io/2018/07/18/how-flutter-inheritedwidget-works/
[21]provider: https://pub.dev/packages/provider
[22]杩欓噷: https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
[23]BlOC: https://medium.com/flutterpub/architecting-your-flutter-project-bd04e144a8f1
[24]RxDart: https://pub.dev/packages/rxdart
[25]Combine: https://developer.apple.com/documentation/combine
[26]Flutter Redux: https://pub.dev/packages/flutter_redux
[27]Fish Redux: https://github.com/alibaba/fish-redux
[28]Mobx: https://mobx.pub/
[29]Do whatever is less awkward: https://github.com/reduxjs/redux/issues/1287#issuecomment-175351978
[30]鍖呬粨搴? https://pub.dev/
[31]杩欓噷: https://github.com/flutter/flutter/wiki/Desktop-shells
[32]浼樼己鐐? https://medium.com/asos-techblog/flutter-vs-react-native-for-ios-android-app-development-c41b4e038db9
[33]Flutter Blog: https://www.yuque.com/xytech/flutter
鈼?nbsp;
鈼?nbsp;
鈼?nbsp;
路END路
姹囪仛绮惧僵鐨勫厤璐瑰疄鎴樻暀绋?/span>
鍠滄鏈枃锛岀偣涓€?span>鍦ㄧ湅鈥濆憡璇夋垜
以上是关于鍐欑粰鍓嶇宸ョ▼甯堢殑 Flutter 鏁欑▼的主要内容,如果未能解决你的问题,请参考以下文章
杩欎唤涔﹀崟锛屾兂瑕佹檵绾ч珮绾ava宸ョ▼甯堢殑鏈嬪弸鍊煎緱涓€鐪嬶紒