flutter入门之通过GridView和PageView实现展示item的功能

    【原创不易,转载请注明出处:https://blog.csdn.net/email_jade/article/details/87915598

    今天给大家带来的是一个非常常见的布局,通过GridViewPageView实现类似于聊天表情emoji布局的功能,我们先来看一下效果吧:

    看了标题大家应该清楚,组成该布局的主体元素是GridViewPageView

    我们来分解一下布局,布局见上下两部分,上面的图标和下面的页指示器,页指示器比较简单,一个居中的Row布局搞定,如下,其中_pageCount代表总页数:

  ///页标
  Widget _buildCursor() {
    List<Widget> list = List();
    for (int i = 0; i < _pageCount; i++) {
      list.add(_buildPoint(_currentPage == i));
    }
    return Container(
      child: Row(
        children: list,
        mainAxisSize: MainAxisSize.min,
      ),
      alignment: AlignmentDirectional.center,
    );
  }

  ///单个点
  Widget _buildPoint(bool focus) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Container(
          width: 10, height: 10, color: focus ? Colors.black : Colors.grey),
    );
  }

    图标部分,单页可以看做是一个GridView,而多个GridView又组成了一个PageView,由于翻页的时候要联动下面的页指示器跟着改变,因此要使用到PageView的PageController动态改变页数,代码如下,要记得及时释放controller:

    

  final List<Widget> children;
  final int column; //列数
  final int row; //行数
  final double columnSpacing; //列间隔
  final double rowSpacing; //行间隔
  final double itemRatio; //每个item的宽高比,默认正方形


  。。。。

   ///每页的个数
  int _countPerPage;
  ///总页数
  int _pageCount;
  ///当前页
  int _currentPage;
  ///控制器
  PageController _controller;


  ///计算总页数及单页的item数目
  void _calculatePage() {
    assert(widget.children != null);
    _countPerPage = widget.row * widget.column;
    _pageCount = (widget.children.length / _countPerPage).ceil();
  }

  ///多个Item构建单页的GridView
  Widget _buildGrid(List<Widget> list) {
    return GridView.count(
      crossAxisCount: widget.column,
      children: list,
      mainAxisSpacing: widget.rowSpacing,
      crossAxisSpacing: widget.columnSpacing,
      childAspectRatio: widget.itemRatio,
    );
  }

  ///构建多个GridView
  List<Widget> _buildPages() {
    List<Widget> list = List();
    int index = 0;
    int realIndex;
    for (int i = 0; i < _pageCount; i++) {
      realIndex = index + _countPerPage > widget.children.length
          ? widget.children.length
          : index + _countPerPage;
      List l = widget.children.sublist(index, realIndex);
      index = realIndex;
      list.add(_buildGrid(l));
    }
    return list;
  }

  ///多个GridView构建PageView
  Widget _buildPageView() {
    return PageView(
      controller: _controller,
      children: _buildPages(),
      onPageChanged: (page) {
        setState(() {
          _currentPage = page;
        });
      },
    );
  }

   

    布局已经完成,比较简单。当然,其实有很多内容可以扩展,比如可以通过Container的BoxDecoration shape属性shape: BoxShape.circle改变页指示器为圆形,也可以通过修改item动态改变样式,比如说是图片和标题组成的Item,等等,都由实际情况来决定,只要大体结构不变,就可以使用此模块。

    下面是使用部分,演示的时候用到了fluttertoast控件:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: GridPage(children: _buildChildren(), column: 7, row: 4,),
    );
  }

  ///构建数据
  List<Widget> _buildChildren(){
    List<Widget> list = List();
    for(int i=0; i<133; i++){
      list.add(GestureDetector(child:Icon(Icons.android, color: Colors.green, size: 40.0,), onTap: (){
        Fluttertoast.showToast(msg: "item $i on click");
      },),);
    }
    return list;
  }
}

     完整代码见:

     https://github.com/jadennn/flutter_grid_page

     flutter很好,路还很长,让我们一起奋斗前行!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值