zoukankan      html  css  js  c++  java
  • 【Flutter实战】自定义滚动条

    老孟导读:【Flutter实战】系列文章地址:http://laomengit.com/guide/introduction/mobile_system.html

    默认情况下,Flutter 的滚动组件(比如 ListView)没有显示滚动条,使用 Scrollbar 显示滚动条:

    Scrollbar(
      child: ListView.builder(
        reverse: false,
        itemBuilder: (BuildContext context, int index) {
          return Card(
            child: Container(
              height: 45,
              alignment: Alignment.center,
              child: Text('$index'),
            ),
          );
        },
        itemCount: 30,
        itemExtent: 50,
      ),
    )
    

    在滑动的过程中,右侧显示滚动条,然而 Scrollbar 无法实现自定义滚动条的样式,比如实现如下滚动条样式,

    这时需要自定义一个滚动条组件。

    实现自定义滚动条组件首先需要监听滚动组件 滚动的位置,使用 NotificationListener 监听滚动的位置:

    bool _handleScrollNotification(ScrollNotification notification) {
        final ScrollMetrics metrics = notification.metrics;
        print('滚动组件最大滚动距离:${metrics.maxScrollExtent}');
        print('当前滚动位置:${metrics.pixels}');
        return true;
      }
    
      @override
      Widget build(BuildContext context) {
        return NotificationListener<ScrollNotification>(
          onNotification: _handleScrollNotification,
          child: ListView.builder(
            reverse: false,
            itemBuilder: (BuildContext context, int index) {
              return Card(
                child: Container(
                  height: 45,
                  alignment: Alignment.center,
                  child: Text('$index'),
                ),
              );
            },
            itemCount: 30,
            itemExtent: 50,
          ),
        );
      }
    

    通过 ScrollNotification 获取当前滚动组件最大滚动距离和当前滚动位置,其中 metrics.maxScrollExtent 表示当前滚动组件最大滚动距离,metrics.pixels 表示当前滚动位置。

    通过这两个值计算滚动条在当前屏幕的位置,通过 Stack 组件 将 ListView 和 自定义的滚动条进行叠加显示:

    NotificationListener<ScrollNotification>(
      onNotification: _handleScrollNotification,
      child: Stack(
        alignment: Alignment.topRight,
        children: <Widget>[
          ListView.builder(
            reverse: false,
            itemBuilder: (BuildContext context, int index) {
              return Card(
                child: Container(
                  height: 45,
                  alignment: Alignment.center,
                  child: Text('$index'),
                ),
              );
            },
            itemCount: 30,
            itemExtent: 50,
          ),
          //滚动条
          Container(
            height: 100,
             20,
            color: Colors.red,
          )
        ],
      ),
    )
    

    将此滚动条和 NotificationListener 监听到的滚动事件联动,通过 Container 的 alignment 属性控制滚动条的位置:

    Container(
      alignment: Alignment(1, _alignmentY),
      padding: EdgeInsets.only(right: 5),
      child: Container(
        height: 100,
         20,
        color: Colors.red,
      ),
    )
    

    _alignmentY 就是计算出的偏移位置,计算方法如下:

    _alignmentY = -1 + (metrics.pixels / metrics.maxScrollExtent) * 2;
    

    这里要注意 alignment 的坐标系:

    最终效果:

    然后只需修改滚动条的样式即可:

    class _ScrollBar extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
           18,
          height: 60,
          decoration: BoxDecoration(
              shape: BoxShape.rectangle,
              borderRadius: BorderRadius.all(Radius.circular(20)),
              color: Colors.blue),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Icon(
                Icons.arrow_drop_up,
                size: 18,
              ),
              Icon(
                Icons.arrow_drop_down,
                size: 18,
              ),
            ],
          ),
        );
      }
    }
    

    最后将代码封装,就可以给所有的滚动组件添加自定义的滚动条,而不仅仅是 ListView。

    交流

    老孟Flutter博客地址(330个控件用法):http://laomengit.com

    欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

  • 相关阅读:
    FC/NES 音乐示例程序 生日快乐歌
    FC/NES PPU卷轴滚屏示例 歌词显示
    HZK16汉字16*16点阵字库的使用及示例程序
    6502 通用宏汇编器宏汇编伪指令说明
    "在您可以登录前, 此版本的 Windows 必须被 Microsoft 激活. 你想现在激活它吗?" 在 XP SP3 中的一种解决方案
    使用 WM_COPYDATA 在进程间共享数据
    51驱动1602液晶显示器的程序
    汉字 全角字符 特殊关键字 ASCII编码区位
    actionscript(as) 项目中 使用 fla 加载 fla
    未能加载文件或程序集“WebGrease, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
  • 原文地址:https://www.cnblogs.com/mengqd/p/13205929.html
Copyright © 2011-2022 走看看