flutter環(huán)境和運(yùn)行環(huán)境搭建好之后燃辖,可以開(kāi)始擼碼了鬼店,然而當(dāng)你打開(kāi)VScode,在打開(kāi)項(xiàng)目文件夾后黔龟,擺在你面前的是main.dart被打開(kāi)的樣子妇智,里面七七八八的已經(jīng)寫(xiě)好了一堆代碼,是不是很懵逼氏身?
不要緊巍棱,人家官方文檔上說(shuō)了,flutter的玩家不需要Dart和移動(dòng)端語(yǔ)言開(kāi)發(fā)經(jīng)驗(yàn)蛋欣,只需要熟悉面向?qū)ο缶幊碳纯伞?br> 神馬航徙?面向?qū)ο笠膊欢窟€是百度打打基礎(chǔ)去吧陷虎。到踏。倒得。
先來(lái)點(diǎn)下酒菜
簡(jiǎn)單了解下上圖中的幾個(gè)標(biāo)記的編號(hào):
A. main.dart
此文件是每一個(gè)flutter項(xiàng)目的默認(rèn)入口文件,也就是說(shuō)每個(gè)flutter項(xiàng)目啟動(dòng)的時(shí)候夭禽,默認(rèn)先運(yùn)行這個(gè)文件的代碼霞掺,這個(gè)入口文件理論上應(yīng)該是可以配置的,不過(guò)我還不知道在哪配讹躯,大神請(qǐng)留言菩彬,嘿嘿。注意看它所在的路徑潮梯,在項(xiàng)目根目錄的lib文件下骗灶,而文件的后綴名.dart是flutter文件的格式,是不是很容易聯(lián)想到flutter使用的dart語(yǔ)言秉馏。
B.import 'package:flutter/material.dart';
每一個(gè).dart文件的第一行都會(huì)導(dǎo)入flutter/material.dart包耙旦,這個(gè)包是Flutter實(shí)現(xiàn)Material Design設(shè)計(jì)風(fēng)格的基礎(chǔ)包,里面有文本輸入框(Text)萝究、圖標(biāo)(Icon)免都、圖片(Image)、行排列布局(Align)帆竹、列排列布局(Column)绕娘、Decoration(我也不知道是啥)、異步(%#¥@暈倒..)栽连、動(dòng)畫(huà)等等等等控件险领,大家可以理解為網(wǎng)頁(yè)中的按鈕、標(biāo)題秒紧、選項(xiàng)框呀等等控件庫(kù)吧绢陌。
Material Design是啥?是谷歌推出的一套視覺(jué)設(shè)計(jì)語(yǔ)言熔恢。比如有的APP可以換皮膚脐湾,而每一套皮膚就是一種設(shè)計(jì)語(yǔ)言,有古典風(fēng)呀炫酷風(fēng)呀極簡(jiǎn)風(fēng)呀神馬的绩聘,而Material Design就是谷歌風(fēng)沥割,有興趣的同學(xué)可以學(xué)習(xí)了解一下Material Design官方原版和Material Design中文翻譯版,這是每一個(gè)產(chǎn)品經(jīng)理的必修教材凿菩。
C.void main() => runApp(new MyApp());
有點(diǎn)像ES6語(yǔ)法的箭頭函數(shù)是不是机杜?對(duì)學(xué)習(xí)過(guò)前端開(kāi)發(fā)的同學(xué)是不是很熟悉呀,意思等同于:
void main() {
return runApp(Widget app);
}
這里的main()
函數(shù)是Dart程序的入口衅谷,也就是說(shuō)椒拗,F(xiàn)lutter程序在運(yùn)行的時(shí)候,第一個(gè)執(zhí)行的函數(shù)就是main()函數(shù),結(jié)合A的入口文件蚀苛,flutter項(xiàng)目默認(rèn)執(zhí)行的第一句代碼在验,就是main.dart文件里的void main() => runApp(new MyApp());
D和E.StatelessWidget
和StatefulWidget
這是flutter最基礎(chǔ)的的兩種控件類(lèi),分別叫無(wú)狀態(tài)類(lèi)和有狀態(tài)類(lèi)堵未,兩者的差別在于是否有狀態(tài)腋舌,玩家創(chuàng)建的所有控件都繼承自這兩個(gè)控件。當(dāng)你想展示的內(nèi)容只需要改動(dòng)控件本身的配置信息就可以實(shí)現(xiàn)時(shí)渗蟹,例如文本块饺、圖片等,可以考慮使用無(wú)狀態(tài)控件(StatelessWidget)雌芽。如果你想展示的內(nèi)容是可以動(dòng)態(tài)改變才能實(shí)現(xiàn)時(shí)授艰,例如滾動(dòng)列表、動(dòng)畫(huà)效果等世落,可以考慮使用有狀態(tài)控件(StatefulWidget)淮腾。
其實(shí)我也不是很明白,StatefulWidget還有生命周期一說(shuō)屉佳,具體怎么回事谷朝,大家可以參考何小有的《Flutter框架基礎(chǔ)》,如果你悟性好忘古,分分鐘貫通也說(shuō)不定徘禁。
寫(xiě)一個(gè)APP試試?
前面寫(xiě)了一大堆廢話髓堪,高手們已經(jīng)不耐煩,萌新們看不懂我也不管了娘荡,擼一管官方萌新教程先~
第一步
把main.dart
里的代碼替換成這個(gè):
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',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Center(
child: new Text('Hello World'),
),
),
);
}
}
保存之后干旁,到終端里輸入這個(gè):
flutter doctor
flutter run
看看你的測(cè)試機(jī)都發(fā)生了什么,好了炮沐,恭喜争群!你的flutter人生的第一個(gè)hallo world告成~!
牢記這一點(diǎn)大年,flutter中的一切都是控件(Widget换薄,有的文章稱呼組件,就當(dāng)作一個(gè)意思吧)翔试,控件是可以嵌套的轻要,嵌套后就會(huì)形成組件樹(shù)。
上面的代碼可以簡(jiǎn)單看看垦缅,能懂多少是多少吧冲泥,對(duì)熟悉面向?qū)ο蟮耐瑢W(xué)應(yīng)該沒(méi)有難度。
第二步
打開(kāi)文件pubspec.yaml
,在這里加一句代碼english_words: ^3.1.0
并保存:
你會(huì)看到終端有動(dòng)作:
再回到*main.dart文件凡恍,加一句代碼import 'package:english_words/english_words.dart';
:
這時(shí)控制臺(tái)的問(wèn)題欄也會(huì)彈出一個(gè)提示:
這是flutter的一個(gè)擼碼規(guī)則志秃,為了保證代碼的高效和簡(jiǎn)潔,避免引入無(wú)用的包造成程序臃腫嚼酝、運(yùn)行效率低下浮还,然后我們?cè)傩薷囊幌麓a并保存:
這時(shí)候APP里的Hello World變成了下面這個(gè)樣子:
到終端中按 r 鍵,在APP中發(fā)現(xiàn)什么變化都沒(méi)有闽巩,而按 R 鍵碑定,APP重啟,屏幕中央的字符串隨機(jī)改變了又官,說(shuō)明APP一旦啟動(dòng)后延刘,玩家創(chuàng)建的無(wú)狀態(tài)控件實(shí)例中的屬性值定義后,刷新頁(yè)面不會(huì)再更新六敬,官方的說(shuō)法是無(wú)狀態(tài)控件實(shí)例中的屬性值為final類(lèi)型碘赖,意味著一旦定義將無(wú)法變更,只有APP重啟后外构,重新執(zhí)行代碼普泡,這時(shí)候重生了控件實(shí)例,所以屏幕中央的字符串改變了审编,但是用 r 還是不會(huì)變撼班。
第三步
這次來(lái)點(diǎn)有難度的,用到了StatefulWidget控件垒酬,請(qǐng)將main.dart
的代碼替換為:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// final wordPair = new WordPair.random();
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Hello Flutter'),
),
body: new Center(
// child: new Text('Hello World'),
// child: new Text(wordPair.asPascalCase), //asPascalCase 駝峰樣式砰嘁,字符串中的每個(gè)單詞的首字母都會(huì)大寫(xiě)
child: new RandomWords(), //定義子控件為有狀態(tài)控件RandomWords的實(shí)例
),
),
);
}
}
//定義了一個(gè)有狀態(tài)控件,繼承自StatefulWidget
class RandomWords extends StatefulWidget {
@override
createState() => new RandomWordsState(); //為StatefulWidget控件RandomWords定義一個(gè)狀態(tài)類(lèi)
}
//定義了一個(gè)狀態(tài)控件勘究,繼承自狀態(tài)類(lèi)State<RandomWords>矮湘,<RandomWords>指明這個(gè)狀態(tài)控件是RandomWords控件的
class RandomWordsState extends State<RandomWords> {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new Text(wordPair.asPascalCase);
}
}
保存代碼后,再到終端口糕,每按一次 r 鍵缅阳,APP中央的字符串就會(huì)隨機(jī)改變,這就是StatefulWidget類(lèi)的特性景描,其實(shí)例內(nèi)的屬性值可以在對(duì)象實(shí)例化后隨意變更十办,一個(gè)StatefulWidget控件至少包含兩個(gè)類(lèi),一個(gè)是用于實(shí)例化的StatefulWidget類(lèi)超棺,一個(gè)是它的State狀態(tài)類(lèi)向族。純粹的StatefulWidget控件本身是不可變的,但是它的State類(lèi)會(huì)在StatefulWidget控件的整個(gè)生命周期持續(xù)存在说搅。
經(jīng)過(guò)這么一折騰炸枣,我也對(duì)StatefulWidget和StatelessWidget的特性有個(gè)了一個(gè)簡(jiǎn)單的認(rèn)識(shí),不知道小伙伴們感覺(jué)如何呀,如果還有不明白的地方适肠,請(qǐng)?jiān)诹粞灾刑釂?wèn)霍衫,flutter圈子說(shuō)不定哪個(gè)大牛心情好會(huì)有解答喲。
本篇就介紹到這里侯养,大家可以自行敲敲代碼敦跌,多體驗(yàn)體驗(yàn),從知道flutter到現(xiàn)在36小時(shí)逛揩,而我能寫(xiě)到這里柠傍,首先感謝技術(shù)達(dá)人狐神的大力支持,幫我拉來(lái)了flutter先驅(qū)何小有和一梭子前端大神辩稽,再者感謝何小有在flutter圈子的入門(mén)掃盲貼投稿惧笛,也感謝大家的支持,我也就不再?gòu)U話什么自我激勵(lì)了逞泄,總之 加油~患整!
再啰嗦一句廣告,對(duì)flutter感興趣的小伙伴可以關(guān)注我喷众,歡迎大家到Flutter圈子中投稿各谚,也可以聯(lián)系管理員加入我們的flutter微信群嗨聊,謝謝捧場(chǎng)~到千!
flutter 中文社區(qū)(官方QQ群:338252156)