??????小菜在學(xué)習(xí)過程中會在一個 Page 頁面同時用到 GridView 和 ListView 或多個 ListView蒋荚,此時就會遇到常見的滑動沖突問題铐尚。小菜嘗試了兩種解決滑動沖突的方案,僅記錄一下基本的使用方式摹闽。小菜翻譯很不到位,可重點看代碼蹈胡。
嘗試一:CustomScrollView + sliver
??????Flutter 提供了類似于 Android CollapsingToolbarLayout 的折疊效果皂贩,小菜借此了解到 CustomScrollView 這個組件罐寨,可以解決列表的滑動沖突。
??????CustomScrollView 允許包含多種滾動模型纵柿,例如列表/網(wǎng)格和擴展標題蜈抓。但其子 Widget 必須為 sliver 類型的。
??????sliver 代表具有特定滾動效果的滾動模型昂儒,sliver 本身不包含滾動交互模型沟使,需要通過 CustomScrollView 連接為一個整體荆忍。sliver 有眾多具體的 Widget格带,小菜也在嘗試過程中。
class _ScrollPageState extends State<ScrollPage3> {
List<int> gridData = List<int>();
_setGridData() {
for (int i = 0; i < 15; i++) {
gridData.add(i);
}
}
@override
void initState() {
_setGridData();
}
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: Text('方案一')), body: _bodyWid());
}
Widget _bodyWid() {
return CustomScrollView(slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return _typeTitleWid('熱門分類');
}, childCount: 1)),
SliverPadding(padding: const EdgeInsets.all(8.0), sliver: _typeGridWid()),
SliverList(
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return _typeTitleWid('智能推薦');
}, childCount: 1)),
_typeListWid()
]);
}
Widget _typeTitleWid(var titleStr) {
return Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding( padding: EdgeInsets.all(10.0),
child: Text(titleStr,
style:
TextStyle(color: Color(0xFF808080), fontSize: 14.0))),
Divider(color: Color(0xFF808080), height: 0.5)
]));
}
Widget _typeGridWid() {
return SliverGrid(
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0, childAspectRatio: 4.0),
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return Container( height: 64.0,
decoration: BoxDecoration(
color: Colors.grey, borderRadius: BorderRadius.circular(3.0)),
child: Center(
child: Text('分類 ${(index + 1)}', style: TextStyle(color: Color(0xFF333333), fontSize: 14.0))));
}, childCount: gridData.length));
}
Widget _typeListWid() {
return SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10.0),
child: Text('推薦精彩內(nèi)容 ${(index + 1)}',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF333333), fontSize: 15.0))),
Padding(
padding: EdgeInsets.only(top: 4.0),
child: Divider(color: Color(0xFF808080), height: 0.5))
]));
}, childCount: gridData.length));
}
}
嘗試二:primary + shrinkWrap
??????小菜在使用 ListView 或 GridView 時發(fā)現(xiàn)有兩個屬性很重要刹枉。小菜的翻譯很不到位叽唱,建議大家仔細閱讀一下官網(wǎng)的介紹。
??????shrinkWrap 常用于內(nèi)容大小不確定情況微宝,如果滾動視圖(ListView/GridView/ScrollView 等)沒有收縮包裝棺亭,則滾動視圖將擴展到允許的最大大小。如果是無界約束蟋软,則 shrinkWrap 必須為 true镶摘。
??????primary 如果為 true,即使?jié)L動視圖沒有足夠的內(nèi)容來支撐滾動岳守,滾動視圖也是可滾動的凄敢。否則,默認為 false 情況下湿痢,只有具有足夠內(nèi)容的用戶才能滾動視圖涝缝。
class _ScrollPageState extends State<ScrollPage3> {
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: Text('方案二')), body: _bodyWid2());
}
Widget _typeGridWid2() {
return GridView.count(
primary: false,
shrinkWrap: true,
crossAxisCount: 4,
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
childAspectRatio: 4.0,
padding: EdgeInsets.all(10.0),
children: gridData.map((int index) {
return Container(
height: 64.0,
decoration: BoxDecoration(
color: Colors.grey, borderRadius: BorderRadius.circular(3.0)),
child: Center(
child: Text('分類 ${(index + 1)}',
style: TextStyle(
color: Color(0xFF333333), fontSize: 14.0))));
}).toList());
}
Widget _typeListWid2() {
return ListView.separated(
primary: false,
shrinkWrap: true,
itemCount: gridData.length,
separatorBuilder: (BuildContext context, int index) => new Divider(),
itemBuilder: (context, item) {
return Padding(
padding: EdgeInsets.all(12.0),
child: Text('推薦精彩內(nèi)容 ${(item + 1)}',
style: TextStyle(color: Color(0xFF333333), fontSize: 15.0)));
});
}
Widget _bodyWid2() {
return ListView(children: <Widget>[
_typeTitleWid('熱門分類'),
_typeGridWid2(),
_typeTitleWid('智能推薦'),
_typeListWid2()
]);
}
}
??????小菜的學(xué)習(xí)還很不到位扑庞,如果有不對的地方還希望多多指出。
來源:阿策小和尚