Padding組件
在 html 中常見的布局標簽都有 padding 屬性,但是 Flutter 中很多 Widget 是沒有 padding 屬性。這個時候我們可以用 Padding 組件處理容器與子元素直接的間距。
該組件接收兩個屬性:
- padding :padding 值, EdgeInsetss 設置填充的值
-
child :子組件
例如,要實現前面的網格布局里面的單元格之間的間距,就可以使用Padding組件。
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('FlutterDemo')), body: LayoutDemo(), )); } } class LayoutDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( padding: EdgeInsets.fromLTRB(0, 0, 10, 0), child: GridView.count( crossAxisCount: 2, childAspectRatio: 1.7, children: <Widget>[ Padding( padding: EdgeInsets.fromLTRB(10, 10, 0, 0), child: Image.network('https://img.ivsky.com/img/tupian/li/201810/30/motianlun-005.jpg', fit: BoxFit.cover), ), Padding( padding: EdgeInsets.fromLTRB(10, 10, 0, 0), child: Image.network('https://img.ivsky.com/img/tupian/li/201811/06/xiaosongshu-002.jpg', fit: BoxFit.cover), ), Padding( padding: EdgeInsets.fromLTRB(10, 10, 0, 0), child: Image.network('https://img.ivsky.com/img/tupian/li/201811/06/ludeng-006.jpg', fit: BoxFit.cover), ), Padding( padding: EdgeInsets.fromLTRB(10, 10, 0, 0), child: Image.network('https://img.ivsky.com/img/tupian/li/201811/06/seattle-005.jpg', fit: BoxFit.cover), ), Padding( padding: EdgeInsets.fromLTRB(10, 10, 0, 0), child: Image.network('https://img.ivsky.com/img/tupian/li/201811/07/osaka-005.jpg', fit: BoxFit.cover), ), Padding( padding: EdgeInsets.fromLTRB(10, 10, 0, 0), child: Image.network('https://img.ivsky.com/img/tupian/li/201811/07/mushroom.jpg', fit: BoxFit.cover), ), ], )); } }
Row 水平布局組件
Row組件用於實現水平布局,相比於ListView的水平排列而言,這個Row的寬度是可控的,二者之間的參數也是不一樣的,Row組件技術的參數為:
- mainAxisAlignment :主軸的排序方式
- crossAxisAlignment:次軸的排序方式
- children:組件子元素
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('FlutterDemo')), body: LayoutDemo(), )); } } class LayoutDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: 800.0, width: 400.0, color: Colors.pink, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ IconContainer(Icons.search,color: Colors.blue), IconContainer(Icons.home,color: Colors.orange), IconContainer(Icons.select_all,color: Colors.red), ], ), ); } } class IconContainer extends StatelessWidget{ double size=32.0; Color color=Colors.red; IconData icon; IconContainer(this.icon,{this.color,this.size}); @override Widget build(BuildContext context) { // TODO: implement build return Container( height: 100.0, width: 100.0, color: this.color, child: Center( child: Icon(this.icon,size: this.size,color: Colors.white) ), ); } }
Column 垂直布局組件
Column組件是區別於Row組件的,用於實現垂直布局,接收的參數和上面的Row是一樣的。
class LayoutDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Container( height: 800.0, width: 400.0, color: Colors.pink, child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[ IconContainer(Icons.search,color: Colors.blue), IconContainer(Icons.home,color: Colors.orange), IconContainer(Icons.select_all,color: Colors.red), ], ), ); } }
Expanded組件
Expanded 可以用在 Row 和 Column 布局中 ,用於實現類似web中的Flex布局。
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('FlutterDemo')), body: LayoutDemo(), )); } } class LayoutDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Row( children: <Widget>[ Expanded( flex: 1, child: IconContainer(Icons.search,color: Colors.blue) ), Expanded( flex: 2, child: IconContainer(Icons.home,color: Colors.orange), ), Expanded( flex: 1, child: IconContainer(Icons.select_all,color: Colors.red), ), ], ); } } class IconContainer extends StatelessWidget{ double size=32.0; Color color=Colors.red; IconData icon; IconContainer(this.icon,{this.color,this.size}); @override Widget build(BuildContext context) { // TODO: implement build return Container( height: 100.0, width: 100.0, color: this.color, child: Center( child: Icon(this.icon,size: this.size,color: Colors.white) ), ); } }
上面是實現等分的,既然是類似於Flex的,那么,也可以實現部分固定寬度,剩余部分自適應的效果:
class LayoutDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Row( children: <Widget>[ Expanded( flex: 1, child: IconContainer(Icons.home,color: Colors.orange), ), IconContainer(Icons.search,color: Colors.blue) ], ); } }
最后,我們就可以結合上面的知識,實現下面的布局了:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('FlutterDemo')), body: LayoutDemo(), )); } } class LayoutDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: <Widget>[ Row( children: <Widget>[ Expanded( child: Container( height: 180, color: Colors.black, child: Text('你好Flutter'), ), ) ], ), SizedBox(height: 10), Row( children: <Widget>[ Expanded( flex: 2, child: Container( height: 180, child: Image.network("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2606512668,2361120991&fm=27&gp=0.jpg",fit: BoxFit.cover),
) ), SizedBox(width: 10), Expanded( flex: 1, child: Container( height: 180, child: ListView( children: <Widget>[ Container( height: 85, child: Image.network("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2606512668,2361120991&fm=27&gp=0.jpg",fit: BoxFit.cover),
), SizedBox(height: 10), Container( height: 85, child: Image.network("https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2191520521,2689315141&fm=27&gp=0.jpg",fit: BoxFit.cover),
)
],
)
)
),
],
)
],
);
}
}