带有过滤条件项的列表视图构建器分页(颤振)
Posted
技术标签:
【中文标题】带有过滤条件项的列表视图构建器分页(颤振)【英文标题】:Listview builder pagination with filtered condition items(Flutter) 【发布时间】:2020-08-14 21:36:25 【问题描述】:我在结构下面有一个列表;
class Data
String name;
int id;
bool active;
List<Data> _dataList;
我在 Listview.builder 中使用这个列表,如下所示;
ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: _dataList.length,
itemBuilder: (context, index)
String name= _dataList[index].name;
String id = _dataList[index].id.toString();
bool active= _dataList[index].active;
return
active ?
Card(
elevation: 5,
child: Text(name + id));
)
我还可以根据此获取过滤后显示的总数和总页码;
var activeList = _dataList.where((c) => c.active == true).toList();
var activeCount = activeList.length;
var totalPages = (activecount/20).ceil();
我想添加一个分页(每页 20 个项目)以使用底部栏图标的“”类型导航,具有上一页和下一页逻辑,如何实现?
我尝试了以下逻辑,但没有成功..
建造者方面:
int page = 1;
int pageCount =0;
ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: addedCount < 20 ? addedCount : 20,
itemBuilder: (context, index)
String name= activeList[page == 1 ? index : index + pageCount].name;
String id = activeList[page == 1 ? index : index + pageCount].id.toString();
bool active= activeList[page == 1 ? index : index + pageCount].active;
图标侧:
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center ,
children: <Widget>[
InkWell(
onTap: ()
if (1 < page)page = page - 1; pageCount = pageCount - 20;
else page = 1;
setState(() );,
child: Icon(Icons.arrow_back_ios, size: 35,)),
Text("$page / $totalPages"),
InkWell(
onTap: ()
if (page < totalPages)page = page + 1; pageCount= pageCount+ 20;
else page = totalPages;
setState(() );,
child: Icon(Icons.arrow_forward_ios, size: 35,)),
],
),
【问题讨论】:
【参考方案1】:下面的代码可能会提供一些见解:
class App extends StatefulWidget
@override
AppState createState() => AppState();
class AppState extends State<App>
final List<Data> dataList = <Data>[];
List<Data> currentDataList = <Data>[];
int page = 1;
int pageCount = 20;
int startAt = 0;
int endAt;
int totalPages = 0;
@override
void initState()
for (var i = 1; i <= 100; i++) dataList.add(Data(name: "Test - $i", id: i));
endAt = startAt + pageCount;
totalPages = (dataList.length / pageCount).floor();
if (dataList.length / pageCount > totalPages)
totalPages = totalPages + 1;
currentDataList = dataList.getRange(startAt, endAt).toList();
super.initState();
void loadPreviousPage()
if (page > 1)
setState(()
startAt = startAt - pageCount;
endAt = page == totalPages
? endAt - currentDataList.length
: endAt - pageCount;
currentDataList = dataList.getRange(startAt, endAt).toList();
page = page - 1;
);
void loadNextPage()
if (page < totalPages)
setState(()
startAt = startAt + pageCount;
endAt = dataList.length > endAt + pageCount ? endAt + pageCount : dataList.length;
currentDataList = dataList.getRange(startAt, endAt).toList();
page = page + 1;
);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('Pagination'),
),
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: currentDataList.length,
itemBuilder: (context, index)
return Card(
elevation: 5,
child: Text(
currentDataList[index].name +
currentDataList[index].id.toString(),
),
);
,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
IconButton(
onPressed: page > 1 ? loadPreviousPage : null,
icon: Icon(
Icons.arrow_back_ios,
size: 35,
),
),
Text("$page / $totalPages"),
IconButton(
onPressed: page < totalPages ? loadNextPage : null,
icon: Icon(
Icons.arrow_forward_ios,
size: 35,
),
),
],
),
],
),
);
【讨论】:
这是一种优雅的方法。我的情况只有一个问题,我的列表来自带有查询的firebase数据库,我在initstate中处理查询,所以当我尝试使用你的逻辑时,我的主列表在initstate期间看起来是空的并导致范围错误但我处理它以某种方式。非常感谢。以上是关于带有过滤条件项的列表视图构建器分页(颤振)的主要内容,如果未能解决你的问题,请参考以下文章