視訊目錄在文章最後,你可以跳到最後進行觀看
Flutter第二季學完,你已經可以作一些效果出來了。但是你想隨心所欲的進行佈局頁面效果,還是感覺有些吃力,這個你不要擔憂,這季教程學完你就可以精通Flutter的佈局了,並且在對Flutter的瞭解上有更深層次的瞭解。
這季裡我我會講解水平佈局、垂直佈局、GridView佈局、ListView佈局、Container佈局......等多種佈局形式。
你學習這季視訊,最好可以先學一下前兩季,這樣可以保證你學起來更順暢和容易。貼出前兩季的文章路徑。
-
第一季Flutter視訊教程地址:jspang.com/post/flutte…
-
第二季Flutter視訊教程地址:jspang.com/post/flutte…
當然,如果你想和大家一起學習和討論,還可以加入專門的Flutter群,我們一起學習。
第01節:水平佈局Row的使用
Flutter中的row控制元件就是水平控制元件,它可以讓Row裡邊的子元素進行水平排列。
Row控制元件可以分為靈活排列和非靈活排列兩種,這兩種模式都需要熟練掌握,等經驗豐富後可根據需求進行使用。
不靈水平佈局
從字面上就可以理解到,不靈活就是根據Row子元素的大小,進行佈局。如果子元素不足,它會留有空隙,如果子元素超出,它會警告。
比如現在我們要製作三個按鈕,並讓三個按鈕同時在一排。我們寫下了如下程式碼,但你會發現效果並不理想。
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('水平方向佈局'),
),
body:new Row(
children: <Widget>[
new RaisedButton(
onPressed: (){
},
color:Colors.redAccent,
child:new Text('紅色按鈕')
),
new RaisedButton(
onPressed: (){
},
color:Colors.orangeAccent,
child: new Text('黃色按鈕'),
),
new RaisedButton(
onPressed: (){
},
color:Colors.pinkAccent,
child:new Text('粉色按鈕')
)
],
)
),
);
}
}
複製程式碼
這時候你會發現的頁面已經有了三個按鈕,但這三個按鈕並沒有充滿一行,而是出現了空隙。這就是不靈活橫向排列造成的。它根據子元素的大小來進行排列。如果我們想實現充滿一行的效果,就要使用靈活水平佈局了。
靈活水平佈局
解決上面有空隙的問題,可以使用 Expanded
來進行解決,也就是我們說的靈活佈局。我們在按鈕的外邊加入Expanded就可以了,程式碼如下:
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('水平方向佈局'),
),
body:new Row(
children: <Widget>[
Expanded(child:new RaisedButton(
onPressed: (){
},
color:Colors.redAccent,
child:new Text('紅色按鈕')
)),
Expanded(child:new RaisedButton(
onPressed: (){
},
color:Colors.orangeAccent,
child: new Text('黃色按鈕'),
)
),
Expanded(child:new RaisedButton(
onPressed: (){
},
color:Colors.pinkAccent,
child:new Text('粉色按鈕')
)
)
],
)
),
);
}
}
複製程式碼
這時候就可以佈滿一行了,效果如下圖。
靈活和不靈活的混用
如果這時候想讓中間的按鈕大,而兩邊的按鈕保持真實大小,就可以不靈活和靈活模式進行混用,實現效果。程式碼和效果如下:
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('水平方向佈局'),
),
body:new Row(
children: <Widget>[
new RaisedButton(
onPressed: (){
},
color:Colors.redAccent,
child:new Text('紅色按鈕')
),
Expanded(child:new RaisedButton(
onPressed: (){
},
color:Colors.orangeAccent,
child: new Text('黃色按鈕'),
)
),
new RaisedButton(
onPressed: (){
},
color:Colors.pinkAccent,
child:new Text('粉色按鈕')
)
],
)
),
);
}
}
複製程式碼
第02節:垂直佈局Column元件
Column元件即垂直佈局控制元件,能夠將子元件垂直排列。其實你學會了Row元件就基本掌握了Column元件,裡邊的大部分屬性都一樣,我們還是以文字為例子,來看看Column佈局。
Column基本用法
寫一段程式碼,在column里加入三行文字,然後看一下效果。
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('垂直方向佈局'),
),
body:Column(
children: <Widget>[
Text('I am JSPang'),
Text('my website is jspang.com'),
Text('I love coding')
],
)
),
);
}
}
複製程式碼
這時候你會發現文字是以最長的一段文字居中對齊的,看起來很彆扭。那如果想讓文字以左邊開始對齊,只需要加入一個對齊屬性。
左對齊只要在column元件下加入下面的程式碼,就可以讓文字左對齊。
crossAxisAlignment: CrossAxisAlignment.start,
複製程式碼
- CrossAxisAlignment.star:居左對齊。
- CrossAxisAlignment.end:居右對齊。
- CrossAxisAlignment.center:居中對齊。
主軸和副軸的辨識
在設定對齊方式的時候你會發現右mainAxisAlignment屬性,意思就是主軸對齊方式,那什麼是主軸,什麼又是幅軸那。
-
main軸:如果你用column元件,那垂直就是主軸,如果你用Row元件,那水平就是主軸。
-
cross軸:cross軸我們稱為幅軸,是和主軸垂直的方向。比如Row元件,那垂直就是幅軸,Column元件的幅軸就是水平方向的。
主軸和幅軸我們搞清楚,才能在實際工作中隨心所欲的進行佈局。
比如現在我們要把上面的程式碼,改成垂直方向居中。因為用的是Column元件,所以就是主軸方向,這時候你要用的就是主軸對齊了。
mainAxisAlignment: MainAxisAlignment.center,
複製程式碼
現在全部的程式碼如下:
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('垂直方向佈局'),
),
body:Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('I am JSPang'),
Text('my website is jspang.com'),
Text('I love coding')
],
)
),
);
}
}
複製程式碼
現在的效果如圖:
水平方向相對螢幕居中
讓文字相對於水平方向居中,我們如何處理?其實只要加入Center元件就可以輕鬆解決。
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('垂直方向佈局'),
),
body:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(child:Text('I am JSPang')),
Center(child:Text('my website is jspang.com')),
Center(child:Text('I love coding'))
],
)
),
);
}
}
複製程式碼
Expanded屬性的使用
其實在學習水平佈局的時候我們對Expanded有了深刻的理解,它就是靈活佈局。比如我們想讓中間區域變大,而頭部區域和底部根據文字所佔空間進行顯示。
body:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(child:Text('I am JSPang')),
Expanded(child:Center(child:Text('my website is jspang.com'))),
Center(child:Text('I love coding'))
],
)
複製程式碼
在Flutter裡的佈局個人覺得是很靈活的,但這就和我們寫Html+CSS是一樣的,我們需要些練習去熟悉它。動手練習一下吧,理論上我們學會了水平和垂直佈局,已經可以布出我們想要的任何介面了。
第03節:Stack層疊佈局
水平佈局和垂直佈局確實很好用,但是有一種情況是無法完成的,比如放入一個圖片,圖片上再寫一些字或者放入容器,這時候Row和Column就力不從心了。Flutter為這種情況準備了Stack層疊佈局,這節就主要學習一下。
比如我們現在要作的效果如下:
在頭像上方再放入一個容器,容器裡邊寫上字,這時候我們就可以使用Stack佈局。
層疊佈局的 alignment 屬性
alignment屬性是控制層疊的位置的,建議在兩個內容進行層疊時使用。它有兩個值X軸距離和Y軸距離,值是從0到1的,都是從上層容器的左上角開始算起的。(視訊中具體演示)
CircleAvatar元件的使用
CircleAvatar
這個經常用來作頭像的,元件裡邊有個radius
的值可以設定圖片的弧度。
現在我們準備放入一個影象,然後把弧度設定成100,形成一個漂亮的圓形,程式碼如下:
new CircleAvatar(
backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
radius: 100.0,
),
複製程式碼
效果程式碼
想佈局出這個效果還是比較容易的,程式碼如下:
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
var stack = new Stack(
alignment: const FractionalOffset(0.5, 0.8),
children: <Widget>[
new CircleAvatar(
backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
radius: 100.0,
),
new Container(
decoration: new BoxDecoration(
color: Colors.lightBlue,
),
padding: EdgeInsets.all(5.0),
child: new Text('JSPang 技術胖'),
)
],
);
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('垂直方向佈局'),
),
body:Center(child:stack),
),
);
}
}
複製程式碼
這節我們先簡單的瞭解一下Stack佈局,我們下節課還會介紹Stack佈局的高階用法。
第04節:Stack的Positioned屬性
上節課已經學習了Stack
元件,並且進行了兩個元件的層疊佈局,但是如果是超過兩個元件的層疊該如何進行定位那?這就是我們加今天要學的主角Positioned
元件了。這個元件也叫做層疊定位元件。
Positioned元件的屬性
- bottom: 距離層疊元件下邊的距離
- left:距離層疊元件左邊的距離
- top:距離層疊元件上邊的距離
- right:距離層疊元件右邊的距離
- width: 層疊定位元件的寬度
- height: 層疊定位元件的高度
Demo例項
修改上節課的例子,文字不在放入到container
元件裡,而是直接放入到Positioned裡,並且不再是兩個元件,而是三個子元件,我們先來看要實現的效果。
實現圖片中的佈局,程式碼如下:
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
var stack = new Stack(
children: <Widget>[
new CircleAvatar(
backgroundImage: new NetworkImage('http://jspang.com/static//myimg/blogtouxiang.jpg'),
radius: 100.0,
),
new Positioned(
top:10.0,
left:10.0,
child: new Text('JSPang.com'),
),
new Positioned(
bottom:10.0,
right:10.0,
child: new Text('技術胖'),
)
],
);
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('層疊佈局'),
),
body:Center(child:stack),
),
);
}
}
複製程式碼
是不是覺的有了層疊佈局,我們在Flutter中的佈局就更加靈活了那。小夥伴們可以動手實現一個你常見的佈局效果。
第05節:卡片元件佈局
Flutter還有一種比較比較酷炫的佈局方式,我稱 它為卡片式佈局。這種佈局類似ViewList,但是列表會以物理卡片的形態進行展示。
例項開發
比如我們現在要開發一個類似收穫地址的列表,並且列表外部使用一個卡片式佈局。
卡片式佈局預設是撐滿整個外部容器的,如果你想設定卡片的寬高,需要在外部容器就進行制定。製作的效果如圖。
程式碼中使用了一個垂直佈局元件Column元件,然後利用了ListTile
實現內部列表,這裡需要說明的是ListTile不光可以使用在ListView元件中,然後容器元件其實都可以使用。程式碼如下.
import 'package:flutter/material.dart';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context ){
var card = new Card(
child: Column(
children: <Widget>[
ListTile(
title:new Text('吉林省吉林市昌邑區',style: TextStyle(fontWeight: FontWeight.w500),),
subtitle: new Text('技術胖:1513938888'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),
ListTile(
title:new Text('北京市海淀區中國科技大學',style: TextStyle(fontWeight: FontWeight.w500),),
subtitle: new Text('勝巨集宇:1513938888'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),
ListTile(
title:new Text('河南省濮陽市百姓辦公樓',style: TextStyle(fontWeight: FontWeight.w500),),
subtitle: new Text('JSPang:1513938888'),
leading: new Icon(Icons.account_box,color: Colors.lightBlue,),
),
new Divider(),
],
),
);
return MaterialApp(
title:'ListView widget',
home:Scaffold(
appBar:new AppBar(
title:new Text('卡片佈局'),
),
body:Center(child:card),
),
);
}
}
複製程式碼
加入QQ群一起學習
學習討論QQ群:674639629(千人群)
入群問題:Flutter出自於哪個公司?
入群答案:google
視訊觀看地址
第一節視訊:www.bilibili.com/video/av358…
第二節視訊:www.bilibili.com/video/av358…
第三節視訊:www.bilibili.com/video/av358…