flutter自定义分页器

flutter自定义分页器,第1张

使用flutter自定义一个分页器

最近在写flutter项目,项目刚好需要一个分页器,对数据进行分页处理,一开始想要在网上找有没有已经写好的插件,搜寻一会后还是想着自己写一个。

先看看效果图

思路 首先要准备一个盒子,装载分页数字。其次要考虑数据总数量在一定范围内该如何进行分页比较合理,比如:展示的要有多少的页数,隐藏起来要有多少的页数,从而对盒子进行规划并且当页数改变的时候,对盒子内的页码参数进行合适的变化 以上是我的简单思路,具体还是看看源码 第一,因为分页器的内容需要时常改变,所以,要使用 StatefulWidget
	class Pager extends StatefulWidget {
	  const Pager({Key? key}) : super(key: key);
	
	  @override
	  State createState() => _PagerState();
	}
	
	class _PagerState extends State {
	  @override
	  Widget build(BuildContext context) {
	    return Container();
	  }
	}
第二,准备展示具体的页码参数,我的思路是根据页码生成对应的widget,所以存放页码的容器使用 list ,但是这个数组需要根据你需要在页面上展示多少的可见页码和隐藏页码来决定
	class _PagerState extends State {
	  List _list = [];  // 存放页码的数组
	  int _total = 10;  // 页码数量(总数据量/一页需要展示多少条数据)
	  int _pageIndex = 1;  // 当前页码
	  
	
	  /*
	      假如:
	        在一行上展示七个页码item,那么要对total进行分配,并且需要根据当前的页码来决定list里面页码的规划
	   */
	  void managePage(){
	    _list = [];  // 将页码数组制空
	    if(_total <= 1) {  // 当页码数量小于等于1时就不需要页码了,直接跳过,此时list为空数组
	      return;
	    }
	    if(_total <= 7) {  // 7:是我自己规定一行内展示的页码item数量,需要展示多少可以自己定义,当小于等于7时,直接进行展示这7个页码item
	      for(var i = 0; i < _total; i++) {
	        _list.add(i+1);
	      }
	    } else if(_pageIndex <= 4) {  // 当页码大于7后,则需要根据当前页码对有些页码进行隐藏
	      _list = [1,2,3,4,5, "...", _total];
	    } else if(_pageIndex > _total - 3) { // 以此类推
	      _list = [1,2, "...", _total - 3, _total - 2, _total - 1,  _total];
	    } else {   
	      _list = [1, "...", _pageIndex - 1, _pageIndex, _pageIndex + 1, "...", _total];
	    }
      // 页码制定好后,根据自己需求,加上前一页按钮,后一页按钮
	    _list.insert(0, "上一页");
	    _list.add("下一页");
	  }
		
	  @override
	  Widget build(BuildContext context) {
	    return Container();
	  }
	}

第三,将页码展示在页面,在这里行内布局我使用 Row,里面的每个页码我用的容器 Container套入Text组件,样式可以自己根据项目需要定义
	@override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      child: Row(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: _list.mapIndexed((index, ele) {
          if(index == 0) {
            return GestureDetector(
              onTap: () {
                if(_pageIndex > 1) {
                  setState(() {
                    _pageIndex--;
                    // 改变页码在这里发送事件通知
                  });
                }
              },
              child: buildPagerItem(
                  child: ele
              ),
            );
          }
          if(index == _list.length - 1) {
            return GestureDetector(
              onTap: () {
                if(_pageIndex < _total) {
                  setState(() {
                    _pageIndex++;
                    // 改变页码在这里发送事件通知
                  });
                }
              },
              child: buildPagerItem(
                child: ele
              ),
            );
          }
          return GestureDetector(
            onTap: () {
              if(ele != "...") {
                setState(() {
                  if(_pageIndex != ele) {
                    _pageIndex = ele;
                    // 改变页码在这里发送事件通知
                  }
                });
              }
            },
            child: buildPagerItem(
                child: Text(
                  "$ele",
                  // 当前页码对应的组件的样式
                  style: ele == _pageIndex ? TextStyle() : TextStyle()
                )
            ),
          );
        }).toList(),
      ),
    );
  }


  // 在这里我对 build 里面的内容进行抽取
  Widget buildPagerItem({
    required Widget child
  }) {
    return Container(
      width: 100,
      height: 50,
      alignment: Alignment.center,
      decoration: BoxDecoration(),
      margin: EdgeInsets.symmetric(),
      child: child,
    );
  }

最后上全部源码
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';

import 'package:dianying/core/extension/index.dart';

class Pager extends StatefulWidget {

  late TextStyle activeTextStyle;  // 当前页码的文本样式
  late Widget preWidget;  // 上一页的widget
  late Widget nextWidget; // 下一页的widget
  int total;  // 总页码数量
  late double containerWidth;  // 容器的宽度
  late MainAxisAlignment mainAxisAlignment;  // 页码横主轴对齐方式
  late TextStyle normalTextStyle;  // 其他页码的文本样式
  late double pagerItemWidth;  // 页码item的宽度
  late double pagerItemHeight; // 页码item的高度
  late BoxDecoration pagerItemDecoration;  // 页码item的样式
  ValueChanged pageChange;   // 页码改变的回调
  late EdgeInsetsGeometry pagerItemMargin;  // 页码item的边距

  Pager({
    Key? key,
    TextStyle? activeTextStyle,
    Widget? preWidget,
    Widget? nextWidget,
    required this.total,
    double? containerWidth,
    MainAxisAlignment? mainAxisAlignment,
    TextStyle? normalTextStyle,
    double? pagerItemWidth,
    double? pagerItemHeight,
    BoxDecoration? pagerItemDecoration,
    required this.pageChange,
    EdgeInsetsGeometry? pagerItemMargin
  }) :  activeTextStyle = activeTextStyle ?? TextStyle(color: Colors.white,
      fontSize: 14.px),
        preWidget = preWidget ?? Icon(Icons.arrow_left, color: Colors.red, size: 22.px),
        nextWidget = nextWidget ?? Icon(Icons.arrow_right, color: Colors.red, size: 22.px),
        containerWidth = containerWidth ?? double.infinity,
        mainAxisAlignment = mainAxisAlignment ?? MainAxisAlignment.spaceAround,
        normalTextStyle = normalTextStyle ?? TextStyle(color: Colors.red, fontSize: 14.px),
        pagerItemWidth = pagerItemWidth ?? 36.px,
        pagerItemHeight = pagerItemHeight ?? 30.px,
        pagerItemDecoration = pagerItemDecoration ?? BoxDecoration(color: Colors.black, borderRadius: BorderRadius.circular(3.px)),
        pagerItemMargin = pagerItemMargin ?? const EdgeInsets.all(0),
        super(key: key);

  @override
  State createState() => _PagerState();
}

class _PagerState extends State {
  int _pageIndex = 1;
  List _list = [];


  void manageList() {
    _list = [];
    if(widget.total <= 1) {
      return;
    }
    if(widget.total <= 7) {
      for(var i = 0; i < widget.total; i++) {
        _list.add(i+1);
      }
    } else if(_pageIndex <= 4) {
      _list = [1,2,3,4,5, "...", widget.total];
    } else if(_pageIndex > widget.total - 3) {
      _list = [1,2, "...", widget.total - 3, widget.total - 2, widget.total - 1,  widget.total];
    } else {
      _list = [1, "...", _pageIndex - 1, _pageIndex, _pageIndex + 1, "...", widget.total];
    }
    _list.insert(0, widget.preWidget);
    _list.add(widget.nextWidget);
  }

  @override
  Widget build(BuildContext context) {
    return buildContent();
  }


  Widget buildContent() {
    manageList();
    return Container(
      width: widget.containerWidth,
      child: Row(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: widget.mainAxisAlignment,
        children: _list.mapIndexed((index, ele) {
          if(index == 0) {
            return GestureDetector(
              onTap: () {
                if(_pageIndex > 1) {
                  setState(() {
                    _pageIndex--;
                    widget.pageChange(_pageIndex);
                  });
                }
              },
              child: buildPagerItem(
                child: ele
              ),
            );
          }
          if(index == _list.length - 1) {
            return GestureDetector(
              onTap: () {
                if(_pageIndex < widget.total) {
                  setState(() {
                    _pageIndex++;
                    widget.pageChange(_pageIndex);
                  });
                }
              },
              child: buildPagerItem(
                child: ele
              ),
            );
          }
          return GestureDetector(
            onTap: () {
              if(ele != "...") {
                setState(() {
                  if(_pageIndex != ele) {
                    _pageIndex = ele;
                    widget.pageChange(_pageIndex);
                  }
                });
              }
            },
            child: buildPagerItem(
              child: Text(
                "$ele",
                style: ele == _pageIndex ? widget.activeTextStyle : widget.normalTextStyle,
              )
            ),
          );
        }).toList(),
      ),
    );
  }


  Widget buildPagerItem({
    required Widget child
  }) {
    return Container(
      width: widget.pagerItemWidth,
      height: widget.pagerItemHeight,
      alignment: Alignment.center,
      decoration: widget.pagerItemDecoration,
      margin: widget.pagerItemMargin,
      child: child,
    );
  }
}

如果感觉不错,点个赞再走吧!!! 感谢观看!!!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/990481.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存