列表视图构建器的分页与过滤条件项目(Flutter)

问题描述 投票:0回答:1

我有一个如下结构的列表。

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个项目),用"< page totalpage > "类型的导航,底部有图标,有上一页和下一页的逻辑,如何实现?

我试过下面的逻辑,但没有成功......

Builder端。

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,)),
             ],
          ),
list listview flutter pagination
1个回答
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,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.