前言一:接下來一段時間我會陸續更新一些列Flutter文字教程前端
更新進度: 每週至少兩篇;vue
更新地點: 首發於公衆號,次日更新於掘金、思否、開發者頭條等地方;算法
更多交流: 能夠添加個人微信 372623326,關注個人微博:coderwhyshell
但願你們能夠 幫忙轉發,點擊在看,給我更多的創做動力。bash
建立Flutter項目有兩種方式:
經過命令行建立
和經過開發工具建立
微信
經過命令行建立很是簡單,在終端輸入如下命令便可:數據結構
flutter create learn_flutter
複製代碼
我這裏也能夠直接經過Android Studio來進行建立:app
Start a new Flutter project
,以後填寫相關的信息便可,這裏再也不贅述咱們講建立的應用起來跑在模擬器上(我這裏選擇iPhone模擬器,Android也能夠),會看到以下效果:less
默認項目分析:ide
lib
文件夾,裏面會存放咱們編寫的Flutter代碼;main.dart
,它是咱們Flutter啓動的入口文件
,裏面有main函數
;默認代碼分析:
+
符號,上面顯示的數字會遞增;不認識
的代碼,不知道這個內容是如何編寫出來的;做爲初學者,個人建議是將其中全部的代碼所有刪除掉,從零去建立裏面的代碼,這樣咱們才能對Flutter應用程序的結構很是清晰;
作任何的開發,咱們都是從祖傳的Hello World
開始,那麼如今咱們的需求來了:
下面,咱們就動手開始編寫Hello World:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(Text("Hello World", textDirection: TextDirection.ltr));
}
複製代碼
固然,上面的代碼咱們已經實現了在界面上顯示Hello World:
沒有居中
,字體也有點小
;上面的代碼咱們有一些比較熟悉,有一些並不清楚是什麼:
入口都是main函數
,而Flutter是Dart編寫的,因此入口也是main函數;Material是什麼呢
?runApp()函數
又是什麼呢?下面,咱們對不認識的代碼進行一些分析。
runApp是Flutter內部提供的一個函數,當咱們啓動一個Flutter應用程序時就是從調用這個函數開始的
void runApp(Widget app) {
...省略代碼
}
複製代碼
該函數讓咱們傳入一個東西:Widget?
咱們先說Widget的翻譯:
Widget到底什麼東西呢?
所看到的內容
幾乎都是Widget,甚至是內邊距的設置
,咱們也須要使用一個叫Padding的Widget
來作;runApp函數讓咱們傳入的就是一個Widget:
material是什麼呢?
設計風格
,或者叫設計語言
、設計規範
等;顏色
、文字的排版
、響應動畫與過分
、填充
等等;Material風格的Widget
;Text小部件分析:
class Text extends StatelessWidget {
const Text(
this.data, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
this.textWidthBasis,
});
}
複製代碼
StatelessWidget簡單介紹:
abstract class StatelessWidget extends Widget {
// ...省略代碼
}
複製代碼
咱們發現如今的代碼並非咱們想要的最終結果:
Center
;咱們修改代碼以下:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(
Center(
child: Text(
"Hello World",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 36),
),
)
);
}
複製代碼
目前咱們雖然能夠顯示HelloWorld,可是咱們發現最底部的背景是黑色,而且咱們的頁面並不夠結構化。
導航欄
,會有一些背景顏色
等在開發當中,咱們並不須要從零去搭建這種結構化的界面,咱們可使用Material庫,直接使用其中的一些封裝好的組件來完成一些結構的搭建。
咱們經過下面的代碼來實現:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: Center(
child: Text(
"Hello World",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 36),
),
),
),
)
);
}
複製代碼
在最外層包裹一個MaterialApp
Scaffold是什麼呢?
腳手架
,腳手架的做用就是搭建頁面的基本結構;appBar
和body
;title屬性
;咱們可讓界面中存在更多的元素:
嵌套太多
了,不要着急,咱們後面會對代碼重構的import 'package:flutter/material.dart';
main(List<String> args) {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Checkbox(
value: true,
onChanged: (value) => print("Hello World")),
Text(
"贊成協議",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 20),
)
],
),
),
),
)
);
}
複製代碼
不少學習Flutter的人,都會被Flutter的嵌套
勸退,當代碼嵌套過多時,結構很容易看不清晰。
這裏有兩點我先說明一下:
可是,咱們開發一個這麼簡單的程序就出現如此多的嵌套,若是應用程序更復雜呢?
如何建立本身的Widget呢?
在上面的案例中對代碼的重構,咱們使用StatelessWidget便可,因此咱們接下來學習一下若是利用StatelessWidget來對咱們的代碼進行重構;
StatefulWidget咱們放到後面的一個案例中來學習;
StatelessWidget一般是一些沒有狀態(State,也能夠理解成data)須要維護的Widget:
咱們來看一下建立一個StatelessWidget的格式:
class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return <返回咱們的Widget要渲染的Widget,好比一個Text Widget>;
}
}
複製代碼
build方法的解析:
build方法什麼狀況下被執行呢?:
如今咱們就能夠經過StatelessWidget來對咱們的代碼進行重構了
重構後的代碼以下:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: HomeContent(),
),
)
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Checkbox(
value: true,
onChanged: (value) => print("Hello World")),
Text(
"贊成協議",
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 20),
)
],
),
);
}
}
複製代碼
咱們先來看一下案例的最終展現效果:
在咱們的案例中,很明顯一個產品的展現就是一個大的Widget,這個Widget包含以下Widget:
另外,三個展現的標題、描述、圖片都是不同的,因此咱們可讓Parent Widget來決定內容:
class ProductItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
ProductItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(title, style: TextStyle(fontSize: 24)),
Text(desc, style: TextStyle(fontSize: 18)),
Image.network(imageURL)
],
);
}
}
複製代碼
如今咱們就能夠建立三個ProductItem來讓他們展現了:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.blueAccent
),
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ProductItem("Apple1", "Macbook Product1", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg"),
ProductItem("Apple2", "Macbook Product2", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imm9u5zj30u00k0adf.jpg"),
ProductItem("Apple3", "Macbook Product3", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imqlouhj30u00k00v0.jpg"),
],
);
}
}
複製代碼
運行效果以下:
如何能夠解決這個問題呢?
若是咱們但願整個內容距離屏幕的邊緣有必定的間距,怎麼作呢?
咱們如今但願給全部的商品也添加一個內邊距,而且還有邊框,怎麼作呢?
咱們但願給圖片和文字之間添加一些間距,怎麼作呢?
最後,我給出最終實現代碼:
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.blueAccent
),
home: Scaffold(
appBar: AppBar(
title: Text("CODERWHY"),
),
body: HomeContent(),
),
);
}
}
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: <Widget>[
ProductItem("Apple1", "Macbook Product1", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg"),
ProductItem("Apple2", "Macbook Product2", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imm9u5zj30u00k0adf.jpg"),
ProductItem("Apple3", "Macbook Product3", "https://tva1.sinaimg.cn/large/006y8mN6gy1g72imqlouhj30u00k00v0.jpg"),
],
),
);
}
}
class ProductItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
ProductItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
border: Border.all()
),
child: Column(
children: <Widget>[
Text(title, style: TextStyle(fontSize: 24)),
Text(desc, style: TextStyle(fontSize: 18)),
SizedBox(height: 10,),
Image.network(imageURL)
],
),
);
}
}
複製代碼
備註:全部內容首發於公衆號,以後除了Flutter也會更新其餘技術文章,TypeScript、React、Node、uniapp、mpvue、數據結構與算法等等,也會更新一些本身的學習心得等,歡迎你們關注