专栏首页技术人生实现点击"换一批"来切换内容,flutter之CustomScrollView【flutter20个实例之八】

实现点击"换一批"来切换内容,flutter之CustomScrollView【flutter20个实例之八】

一、老套路,先看样式

左图是我业务中的样式,右图是下方源码展示样式(复制可直接运行,无额外组件引入)

二、讲解

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,
        ),
      ),
    );
  }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • php+nginx中的php.ini,php-fpm.conf,nginx.conf【php】

    1.php-fpm.conf:是PHP-FPM特有的配置文件,是PHP-FPM进程管理器的配置文件

    sinnoo
  • flutter组件2【icons的使用】

    sinnoo
  • 谈谈flutter中Checkbox复选框的全选与删除【flutter20个实例之三】

    左侧三张图片是我的实际开发中业务界面,用作展示而已,具体源码效果是右边侧的三张图片。

    sinnoo
  • Docker容器CPU、memory资源限制

    在使用 docker 运行容器时,默认的情况下,docker没有对容器进行硬件资源的限制,当一台主机上运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同...

    飞天小子
  • 什么是星型模型

    星型模型是最简单的数据集市模型,是最广泛用于开发数据仓库和维度数据集市的方法。星型模型由一个或多个引用任意数量的维度表的事实表组成。 星型模型是雪花模型的一个重...

    王小雷
  • Xshell设置全局配色

    院长技术
  • Github上如何在Fork到的开源项目中提交Pull requests?

    如何在 Fork 到的开源项目中提交 Pull requests ?   我们将 Fork 到的开源项目克隆到我们本地计算机中进行修改,把更改通过 Pull ...

    黑泽君
  • Python 常识

    在Python的世界里,通常是用缩进来表示一个段落,所以无论在任何时候,都要注意缩进是否正确,一旦缩进不正确,可能会导致程序的结果异常或者无法执行直接报错。

    py3study
  • Smarty模板语法详解

    smarty注释不会在模板文件的最后输出中出现,这与不同(译注:html注释在页面源码中可见,而smarty注释则不能)。

    砸漏
  • *LinkedList实现原理及源码学习(JDK 1.8.0)*

    (1)继承自抽象类AbstractSequentialList(而AbstractSequentialList又继承自AbstractList);

    一半是我

扫码关注云+社区

领取腾讯云代金券