原作者:Andings
版權(quán)聲明:本文版權(quán)歸本人所有浪默,未經(jīng)作者許可淌铐,不得以任何形式轉(zhuǎn)載
簡介
Flutter學(xué)習(xí)筆記,學(xué)習(xí)途徑包括但不僅限于:Flutter官網(wǎng)陷揪、慕課網(wǎng)、掘金/簡書平臺杂穷。
學(xué)習(xí)編寫第一個Flutter程序
import 'package:flutter/material.dart';
void main() => runApp(HelloWorld());
class HelloWorld extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "第一個Flutter應(yīng)用",
home: new Scaffold(
appBar: new AppBar(
title: new Text("第一個Flutter應(yīng)用"),
),
body: new Center(
child: new Text("Hello World!"),
),
),
);
}
}
思路:
我們首先創(chuàng)建一個HelloWorld類悍缠,讓他繼承自StatelessWidget(玄冥二老之一的widget)
StatelessWidget是我們開發(fā)Flutter中最核心的Widget,stateless意思為狀態(tài)不可改變的Widget,我們常常用來寫一些靜態(tài)頁面耐量,也就是狀態(tài)不需要改變的頁面肯定繼承它了飞蚓,與之對應(yīng)的就是狀態(tài)可以改變的組件視圖StatefullWidget,這兩大組件是Flutter開發(fā)中玄冥二老。
在源碼中是StatelessWidget是一個抽象類廊蜒,子類繼承的話必須實現(xiàn)方法bulid(),返回的是一個Widget對象趴拧,這完全符合開發(fā)思想,既然是不可改變的視圖山叮,那我們直接返回一個組件Widget即可(它總是顯示該Widget)著榴,其他的我們并不需要要關(guān)心,比如視圖改變的情況...
ok,既然build()方法需要我們返回一個Widget屁倔,我們該返回哪一個兄渺?Flutter一切皆組件(所有的視圖都是繼承Widget),是不是返回任意的widget就可以呢汰现?顯然并不是挂谍,這時我們需要返回一個MaterialApp,這是谷歌建議我們遵循Material的風(fēng)格規(guī)范來編寫界面瞎饲,所以口叙,界面上看到都是在MaterialApp中定義的。
MaterialApp是顯示的核心類嗅战,其中常用的屬性有:title和home,其中title是標(biāo)題的意思妄田,直接給一個字符串就好了。
title: 'helloWorld'
我們重點關(guān)心home屬性,Ctrl+鼠標(biāo)左鍵可以查看需要返回什么驮捍,What?疟呐,又是返回Widget?這里將返回一個非常重要的Widget———腳手架Widget,它才是真正是顯示組件,其中定義appBar以及頁面中顯示什么东且,這里用到的屬性標(biāo)簽:appBar和body
home: Scaffold(
appBar: new AppBar(
title: new Text('TextWidget'),
),
body: new Center(
child: Text('HelloWorld'),
),
),
其中启具,appBar里面又有很多屬性,title表明appBar上顯示的文本內(nèi)容珊泳,當(dāng)然還有其他屬性
body表明頁面主題將顯示哪種視圖鲁冯,需要返回的依舊是Widget對象拷沸,這里Center組件表明,內(nèi)容將顯示在視圖中心區(qū)域薯演,然后又是嵌套撞芍,定義Center中的屬性......
總結(jié):
StatelessWidget、build()跨扮、MaterialApp->title->home序无、腳手架Scaffold、appBar衡创、body愉镰、Center->child
- 首先繼承StatelessWidget抽象類,實現(xiàn)bulid方法
- return一個MaterialApp
- 定義App內(nèi)的title,和home
- home屬性需要返回腳手架Scaffold組件
- 腳手架定義appBar和body屬性钧汹,appBar中定義text,body中創(chuàng)建Center
- 在Center居中組件中丈探,利用child屬性,返回一個TextWidget拔莱,用來顯示內(nèi)容
TextWidget
作用:顯示一段文本在界面上碗降,類似于Android中的TextView控件
TextWidget常用屬性有:
- TextAlig:文本對齊屬性
- maxLines:最大顯示行數(shù)
- overflow:控制文本溢出效果
如何控制字體大小,樣式塘秦?textWidget為我們提供了style標(biāo)簽來控制
style: TextStyle(
fontSize: 20.0,
color:Color.fromARGB(255, 255, 150, 150),
decorationStyle: TextDecorationStyle.solid,
decoration: TextDecoration.underline
),
ContainerWidget容器
作用:可以用來放置多個子組件讼渊,類似于Android中的布局Layout,可以對子元素進行布局操作。
常用屬性:
- alignment:子控件對齊方式尊剔,例如:頂部居中alignment: Alignment.topCenter
- width:控件的寬
- height: 控件的高
- color:控件的背景樣色 例如color: Colors.blue,
- padding:內(nèi)間距
- margin:外間距
- decoration:設(shè)置容器邊框
new Container(
child: new Text('Hello World',
style: TextStyle(fontSize: 40),
),
alignment: Alignment.center,
width: 200.0,
height: 400.0,
color: Colors.blue,
padding: EdgeInsets.all(50) ,
margin: EdgeInsets.all(50),
),
圖片組件ImageWidget
圖片的顯示是任何一個應(yīng)用不可或缺的一部分爪幻,圖片比文字更有吸引力,F(xiàn)lutter也為我們提供了非常方便快捷的api须误。
圖片的獲取途徑挨稿?
- Image asset:加載本地圖片資源,會使打包體積變大
- Image.network:網(wǎng)絡(luò)資源圖片京痢,需要經(jīng)常更換或者需要動態(tài)顯示的圖片
- Image file:本地圖片奶甘,例如:相機中的圖片...
- Image memory:加載到內(nèi)存中的圖片,Uint8List,不常用
這里我們介紹一下常用的網(wǎng)絡(luò)圖片加載:
代碼演示
child: new Image.network(
'https://img3.mukewang.com/5c1677390001169809600960-140-140.jpg',
scale: 1.5,
fit: BoxFit.fill,
),
直接new 一個Image.network即可,默認(rèn)需要一個url屬性值即可加載圖片
常用屬性值:
- scale: 圖片的縮放
- fit: 相對于父容器祭椰,圖片拉伸或填充
列表組件ListView
列表組件是我們開發(fā)中用的最多的組件之一臭家,F(xiàn)lutter為我們提供了非常方便的Api調(diào)用,我們并不需要關(guān)系性能問題方淤,直接使用即可钉赁。
這里我們演示一個簡單的例子:
new ListView(
children: <Widget>[
new ListTile(
leading: new Icon(Icons.access_time),
title: new Text('你好'),
),
new Image.network("https://img3.mukewang.com/5c1677390001169809600960-140-140.jpg"),
new Image.network("https://img3.mukewang.com/5c1677390001169809600960-140-140.jpg"),
new Image.network("https://img3.mukewang.com/5c1677390001169809600960-140-140.jpg"),
],
)
new出一個ListView組件后,利用child屬性携茂,返回一個Widget數(shù)組你踩,數(shù)組中的組件將是ListView的數(shù)據(jù)源,我們可以隨意添加Widget,圖片文字都可以。
為了方便每個Widget的組合姓蜂,我們可以使用ListTile這個組件,他是ListView的小瓦片医吊,相當(dāng)于每一個Item钱慢,我,額可以再這個組件中組合圖片或者文字卿堂,這樣每一個listItem就是一個圖片和文字的組合了束莫。
1.ListView動態(tài)(通過傳參的方式)
剛剛只是一個list靜態(tài)列表,數(shù)據(jù)都是寫死的草描,我們現(xiàn)在來做一個動態(tài)的列表览绿,也就是說數(shù)據(jù)是不確定的,由服務(wù)端或者后端傳遞過來的穗慕,我們得到數(shù)據(jù)然后傳遞到列表當(dāng)中進行顯示饿敲,這就涉及到數(shù)據(jù)的傳遞知識,屬于Dart的基礎(chǔ)知識逛绵,我們一起來了解一下怀各。
構(gòu)造器:我們知道在初始化一個類的時候,默認(rèn)是調(diào)用無參的構(gòu)造器术浪,當(dāng)然我們也可以手動添加有參數(shù)的構(gòu)造器瓢对,可以在初始化的時候可以傳參,所以我們在構(gòu)造器中聲明形參來接收傳遞過來的參數(shù)胰苏,下面來看實例:
void main() => runApp(
//這里在初始化對象時硕蛹,傳遞了一個參數(shù)
new ListViews(items: new List<String>.generate(1000, (i) => "Item $i")));
class ListViews extends StatelessWidget {
final List<String> items;
//構(gòu)造器接收參數(shù)
ListViews({Key key, @required this.items}) : super(key: key);
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "dad",
home: new Scaffold(
appBar: new AppBar(
title: new Text('ListView'),
),
body: new ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return new ListTile(title: new Text('${items[index]}'));
}),
),
);
}
}
可以看到,我們在new的時候硕并,傳遞了一個List對象給構(gòu)造器法焰,通過List的generate方法快速生成一個1000大小的列表。
然后在類的構(gòu)造器中去接收到這個List參數(shù)倔毙,然后給類的ListView組件使用壶栋,達(dá)到動態(tài)數(shù)據(jù),list的數(shù)據(jù)源是由外部接受的的普监,這樣我們的ListView數(shù)據(jù)將會非常靈活贵试。
2.橫向列表的使用
橫向列表顧名思義就是,可以通過水平方向進行一個列表的滑動凯正,左右滑動列表Item毙玻,即可瀏覽ListView的數(shù)據(jù)了。
scrollDirection屬性的使用
- Axis.vertical:垂直方向
- Axis.horizontal 水平方向
非常簡單廊散,我們直接修改屬性值就可以完成不同方向的ListView
附上完整代碼:
import 'package:flutter/material.dart';
void main() => runApp(new HorizontalList());
class HorizontalList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('橫向list'),
),
body: new Center(
child: new Container(
height: 200.0,
child: new MyList()
),
),
),
);
}
}
//簡化代碼 提取出來單獨
class MyList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
new Container(
width: 180.0,
color: Colors.amber,
),
new Container(
width: 180.0,
color: Colors.cyanAccent,
),new Container(
width: 180.0,
color: Colors.deepOrange,
),new Container(
width: 180.0,
color: Colors.amber,
),new Container(
width: 180.0,
color: Colors.lightBlue,
),
],
);
}
}