一、老套路,先看樣式
圖一是我業務中的樣式,圖二是下方原始碼展示樣式(複製可直接執行,無額外元件引入)
二、講解
1.結構拆分
首先,頁面是個滾動列表,所以一定需要一個listview來容納
然後每一個item,有個標題,比如精選
標題下方是一個流式佈局,可自動切換行,用到了flutter的wrap元件
結構清晰後,無非就三段程式碼
2.首介面和資料載入
list是我們要迴圈的列表,這個列表是一級分類的資料
然後裡面還有個topic欄位,是二級分類的列表資料
也就是說這個_list欄位是二維陣列感慨念
if (_list.isEmpty) {
return Text('載入中....');
} else {
return ListView.builder(
itemBuilder: (context, index) {
return getItem(_list[index]);
},
itemCount: _list.length,
);
}
複製程式碼
3.每一個item的設定
這裡通過column來設定,一個元件就是標題,第二個元件就是wrap流式佈局
4.wrap流式佈局
我們重要來說這個
Wrap可以為子控制元件進行水平或者垂直方向佈局,且當空間用完時,Wrap會自動換行,也是常說的流式佈局。
Wrap(
alignment: WrapAlignment.spaceBetween,
spacing: 10,
children: List.generate(item['topic'].length, (i) {
return _childList(item['topic'][i]);
}
),
)
複製程式碼
direction
屬性控制佈局方向,預設為水平方向,設定方向為垂直程式碼如下:
Wrap(
direction: Axis.vertical,
...
)
複製程式碼
alignment
屬性控制主軸對齊方式,crossAxisAlignment
屬性控制交叉軸對齊方式,對齊方式只對有剩餘空間的行或者列起作用,例如水平方向上正好填充完整,則不管設定主軸對齊方式為什麼,看上去的效果都是鋪滿。
Wrap(
alignment: WrapAlignment.spaceBetween,
...
)
複製程式碼
spacing
和runSpacing
屬性控制Wrap主軸方向和交叉軸方向子控制元件之間的間隙
verticalDirection
屬性表示Wrap交叉軸方向上子控制元件的方向,取值範圍是up
(從上到下)和down
(從下到上)
三、原始碼(可直接執行除錯)
import 'package:flutter/material.dart';
class Mytest extends StatefulWidget {
Mytest({Key key}) : super(key: key);
_MytestState createState() => _MytestState();
}
class _MytestState extends State<Mytest> {
List _list = [];
@override
void initState() {
super.initState();
this._getData();
}
_getData() async {
//這裡後面要換成資料請求
List ret = [
{
'title': '精選',
'topic': [
{
'title': '標題',
'icon':
'http://n1.c.imoxiu.com/85b4d9acec1b23abf499387f4fe4dd979483f46a/100'
}
]
}
];
setState(() {
this._list = ret;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(body: getHome(),appBar: AppBar(title: Text('流式佈局'),elevation: 0.0,),);
}
Widget getHome() {
if (_list.isEmpty) {
return Text('載入中....');
} else {
return ListView.builder(
itemBuilder: (context, index) {
return getItem(_list[index]);
},
itemCount: _list.length,
);
}
}
Widget getItem(item) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 0, 10),
child: Text(item['title'], style: TextStyle(color: Colors.black38)),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 10, 0, 10),
child: item['topic'].length > 0
? Wrap(
alignment: WrapAlignment.spaceBetween,
spacing: 10,
children: List.generate(item['topic'].length, (i) {
return _childList(item['topic'][i]);
}),
)
: Container(),
),
],
);
}
Widget _childList(topicItem) {
return GestureDetector(
onTap: () {},
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 20,
child: Image.network(
topicItem['icon'],
fit: BoxFit.cover,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(2, 0, 0, 0),
child: Text(
topicItem['title'],
style: TextStyle(fontSize: 12, color: Colors.black),
),
)
],
),
);
}
}
複製程式碼
支援更新中......