Flutter進階—通用佈局控制元件
Flutter有一個豐富的佈局控制元件庫,但我們只學習最常用的一些,目的是使你可以儘快開始開發,而不是按步就班的學習完整的課程。
控制元件分為兩類:控制元件庫(Widgets Library)中的標準控制元件和質感設計庫(Material Library)中的專用控制元件。任何應用程式都可以使用控制元件庫(Widgets Library),但只有質感設計應用程式可以使用質感設計庫(Material Library)。
標準控制元件
Container(容器)
許多佈局可以自由地使用容器來分隔帶有填充的控制元件,或新增邊框、邊距。您可以通過將整個佈局放入容器並更改其背景顏色或影象來更改裝置的背景。
下面的佈局由2行2列組成,每列包含2個影象(pic1.jpg、pic2.jpg、pic3.jpg、pic4.jpg)。每個影象使用容器來新增一個圓形的灰色邊框和邊距,包含影象行的列使用容器將背景顏色更改為較淺的灰色。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
//...
var container = new Container(
decoration: new BoxDecoration(
backgroundColor: Colors.black26,
),
child: new Column(
children: [
new Row(
children: [
new Expanded(
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(width: 10.0, color: Colors.black38),
borderRadius: const BorderRadius.all(const Radius.circular(8.0))
),
margin: const EdgeInsets.all(4.0),
child: new Image.asset('images/pic1.jpg'),
)
),
new Expanded(
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(width: 10.0, color: Colors.black38),
borderRadius: const BorderRadius.all(const Radius.circular(8.0))
),
margin: const EdgeInsets.all(4.0),
child: new Image.asset('images/pic2.jpg'),
)
),
]
),
new Row(
children: [
new Expanded(
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(width: 10.0, color: Colors.black38),
borderRadius: const BorderRadius.all(const Radius.circular(8.0))
),
margin: const EdgeInsets.all(4.0),
child: new Image.asset('images/pic3.jpg'),
)
),
new Expanded(
child: new Container(
decoration: new BoxDecoration(
border: new Border.all(width: 10.0, color: Colors.black38),
borderRadius: const BorderRadius.all(const Radius.circular(8.0))
),
margin: const EdgeInsets.all(4.0),
child: new Image.asset('images/pic4.jpg'),
)
),
]
),
]
)
);
//...
}
}
GridView(網格檢視)
使用GridView將控制元件作為二維列表放置。 GridView提供了兩個預製列表,或者您可以構建自己的自定義網格。當GridView檢測到其內容太長,無法適應渲染框時,它會自動滾動。
下面的佈局使用GridView.extent建立一個最大150畫素寬的圖塊,影象儲存名稱為pic1.jpg、pic2.jpg … pic30.jpg,List.generate建構函式允許建立一個簡單的方法。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
//...
List<Container> _buildGridTileList(int count) {
return new List<Container>.generate(
count,
(int index) => new Container(child: new Image.asset('images/pic${index+1}.jpg'))
);
}
Widget buildGrid() {
return new GridView.extent(
maxCrossAxisExtent: 150.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
children: _buildGridTileList(20)
);
}
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: buildGrid(),
),
);
//...
}
}
ListView(列表檢視)
ListView是一個類列表的控制元件,當其內容對於其渲染框太長時,它會自動提供滾動。
下面的佈局使用ListTiles的業務列表,用分隔線將劇院與餐廳分開。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
//...
List<Widget> list = <Widget>[
new ListTile(
title: new Text('深圳萬達海雅廣場店', style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
subtitle: new Text('深圳市寶安區建安一路海雅繽紛城4樓'),
leading: new Icon(
Icons.theaters,
color: Colors.blue[500],
)
),
//...
new Divider(),
new ListTile(
title: new Text('同仁四季音樂主題餐廳(海岸城店)', style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
subtitle: new Text('海岸城保利文化廣場2樓保利來覓C6(近地鐵後海站E出口)'),
leading: new Icon(
Icons.restaurant,
color: Colors.blue[500],
)
),
//...
];
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new ListView(
children: list,
)
),
);
//...
}
}
Stack(層疊)
使用Stack在基本控制元件頂部排列控制元件,通常像影象,控制元件可以完全或部分地重疊基本控制元件。
下面的佈局使用Stack覆蓋一個容器(在半透明黑色背景上顯示其文字)在圓形頭像頂部。Stack使用alignment屬性和FractionalOffsets來偏移文字。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
//...
var stack = new Stack(
alignment: const FractionalOffset(0.8, 0.8),
children: [
new CircleAvatar(
backgroundImage: new AssetImage('images/pic4.jpg'),
radius: 100.0,
),
new Container(
decoration: new BoxDecoration(
backgroundColor: Colors.black45,
),
child: new Text(
'Hekaiyou',
style: new TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.bold,
color: Colors.white,
)
)
)
]
);
//...
}
}
質感設計控制元件
Card(卡片)
Card包含相關的資訊塊,可以由大多數任何控制元件組成,但經常與ListTile一起使用。Card只有一個子控制元件,但它的子控制元件可以是支援多個子控制元件的列、行、列表、網格或其他控制元件。預設情況下,Card將其大小縮小為0畫素。您可以使用SizedBox限制Card的大小。
在Flutter中,Card具有略微圓角和陰影,給予3D效果。更改Card的elevation屬性可以控制陰影效果。例如,將elevation設定為24,可以將Card從表面進一步提升,並使陰影變得更加分散。
下面的佈局是一張包含3個ListTile的卡片,並用SizedBox包裝大小。分隔符分隔第一個和第二個ListTile。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
//...
var card = new SizedBox(
height: 210.0,
child: new Card(
child: new Column(
children: [
new ListTile(
title: new Text('北京市復興路10號', style: new TextStyle(fontWeight: FontWeight.w500)),
subtitle: new Text('北京市,100844'),
leading: new Icon(
Icons.business,
color: Colors.blue[500],
)
),
new Divider(),
new ListTile(
title: new Text('12306', style: new TextStyle(fontWeight: FontWeight.w500)),
leading: new Icon(
Icons.contact_phone,
color: Colors.blue[500],
)
),
new ListTile(
title: new Text('[email protected]', style: new TextStyle(fontWeight: FontWeight.w500)),
leading: new Icon(
Icons.contact_mail,
color: Colors.blue[500],
)
),
]
)
)
);
//...
}
}
ListTile(列表平鋪)
ListTile是質感設計庫中專門的行控制元件,可以輕鬆建立一行,其中最多包含3行文字和可選的前導和尾隨圖示。 ListTile最常用於Card或ListView,還可以在別的地方使用。