一、老套路,先看樣式
左圖是我業務中的樣式,右圖是下方原始碼展示樣式(複製可直接執行,無額外元件引入)
二、講解
1.涉及元件
首先,沒有一個單一元件來實現這個效果
實現這個效果涉及以下元件:
AppBar:頂端欄,一個最基本的軟體
Text:文字
Container:佈局元件
CustomScrollView:自定義滾動效果元件,比如列表和網格元件都可以包含在其中
SliverGrid:網格檢視元件
SliverList:列表控制元件
InkWell:效果控制元件,可以給其他widget包裹一個點選效果
ListTile:標題元件,通常填充listview
複製程式碼
2.首先設定下標題樣式
getItem是我們的主內容
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: new IconButton(
icon: new Icon(Icons.arrow_back,
color: Colors.black38),
onPressed: () {
print('返回按鈕');
},
),
title: Text('換一批效果'),
centerTitle: true,
elevation: 0.0,
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {},
),
],
), //這個是頂部tab樣式,如果不需要可以去掉
body: Container(
child: getItem(),
));
}
複製程式碼
3.換一批點選效果
我們給換一批樣式設定一個點選效果
當點選的時候,判斷當前內容是否滿足18條(一屏展示的數目)
如果不滿足,說明最後一頁了,重置頁碼為1
如果滿足,說明當前資料>=18,後面可能還有資料,頁碼+1
然後請求資料,_getData()是封裝的一個請求資料函式
SliverList(
delegate: SliverChildListDelegate([
ListTile(
onTap: () {
int Temp = page + 1;
if (_list.length < 18) {
Temp = 1;
}
setState(() {
page = Temp;
});
_getData();
},
title: Text(
'挑選一個圖示吧',
style: TextStyle(color: Colors.black, fontSize: 12),
),
trailing: Text('換一批',
style: TextStyle(color: Colors.black54, fontSize: 10)),
),
]),
),
複製程式碼
4.網格內容其實就是一個SliverGrid,切換資料後,進行了部分頁面重新渲染
三、原始碼(可直接執行除錯)
import 'package:flutter/material.dart';
class AddHabit extends StatefulWidget {
String hid = '';
AddHabit({this.hid});
@override
_AddHabitState createState() => _AddHabitState();
}
class _AddHabitState extends State<AddHabit> {
var _icon = '';
double leftPadding = 15.0;
List _list = [
{
'id': 1,
'image':
'https://daybili.oss-cn-beijing.aliyuncs.com/image/202008/liaotian.png'
}
];
int page = 1;
@override
void initState() {
super.initState();
this._getData();
}
//獲取資料, 為了測試方便, 我處理為了靜態資料
_getData() async {
//_list資料應該是通過網路請求獲得
print(_list);
setState(() {
_list = _list;
});
}
//build初始化
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: new IconButton(
icon: new Icon(Icons.arrow_back, color: Colors.black38),
onPressed: () {
print('返回按鈕');
},
),
title: Text('換一批效果'),
centerTitle: true,
elevation: 0.0,
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () {},
),
],
), //這個是頂部tab樣式,如果不需要可以去掉
body: Container(
child: getItem(),
));
}
//核心內容
Widget getItem() {
return CustomScrollView(slivers: <Widget>[
SliverList(
delegate: SliverChildListDelegate([
ListTile(
onTap: () {
int Temp = page + 1;
if (_list.length < 18) {
Temp = 1;
}
setState(() {
page = Temp;
});
_getData();
},
title: Text(
'挑選一個圖示吧',
style: TextStyle(color: Colors.black, fontSize: 12),
),
trailing: Text('換一批',
style: TextStyle(color: Colors.black54, fontSize: 10)),
),
]),
),
SliverGrid(
//padding: EdgeInsets.zero,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 6, crossAxisSpacing: 5, mainAxisSpacing: 3),
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return habitIcon(_list[index]);
}, childCount: _list.length),
),
]);
}
//某個圖示樣式
Widget habitIcon(item) {
return InkWell(
onTap: () {
setState(() {
_icon = item['id'];
});
},
child: Container(
height: 100,
width: 100,
color: item['id'] == _icon ? Colors.white : Colors.black12,
alignment: Alignment.center,
child: Image.network(
item['image'],
width: 30,
height: 30,
),
),
);
}
}
複製程式碼