【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,
width: 20,
color: Colors.red,
)
],
),
)

将此滚动条和 NotificationListener 监听到的滚动事件联动,通过 Container 的 alignment 属性控制滚动条的位置:
Container(
alignment: Alignment(1, _alignmentY),
padding: EdgeInsets.only(right: 5),
child: Container(
height: 100,
width: 20,
color: Colors.red,
),
)
_alignmentY 就是计算出的偏移位置,计算方法如下:
_alignmentY = -1 + (metrics.pixels / metrics.maxScrollExtent) * 2;
这里要注意 alignment 的坐标系:

最终效果:

然后只需修改滚动条的样式即可:
class _ScrollBar extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 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】:
![]() |
![]() |
【Flutter实战】自定义滚动条的更多相关文章
- 《Flutter实战》开源电子书
<Flutter实战>开源电子书 <Flutter实战> 开源了,本书为 Flutter中文网开源电子书项目,本书系统介绍了Flutter技术的各个方面,本书属于原创书籍(并非 ...
- Flutter实战】文本组件及五大案例
老孟导读:大家好,这是[Flutter实战]系列文章的第二篇,这一篇讲解文本组件,文本组件包括文本展示组件(Text和RichText)和文本输入组件(TextField),基础用法和五个案例助你快速 ...
- CSS3自定义滚动条样式 -webkit-scrollbar(转)
有没有觉得浏览器自带的原始滚动条很不美观,同时也有看到很多网站的自定义滚动条显得高端,就连chrome32.0开发板都抛弃了原始的滚动条,美观多了.那webkit浏览器是如何自定义滚动条的呢? 前言 ...
- jquery自定义滚动条 鼠标移入或滚轮时显示 鼠标离开或悬停超时时隐藏
一.需求: 我需要做一个多媒体播放页面,左侧为播放列表,右侧为播放器.为了避免系统滚动条把列表和播放器隔断开,左侧列表的滚动条需要自定义,并且滚动停止和鼠标离开时要隐藏掉. 二.他山之石: 案例来自h ...
- 利用JS实现自定义滚动条
一般默认的滚动条会比较丑,我们可以用简单的js实现自定义滚动条的功能: 代码如下: <!doctype html> <html> <head> <meta c ...
- javascript 学习之自定义滚动条加滚轮事件
要自己写一个自定义滚动条加上滚轮事件,之前的没有滚轮事件不完整,今天整理了一个. 1.滚轮事件是不兼容的,firefox中是必需要用事件绑定的添加,用的DOMMouseScroll,当滚动鼠标的时候, ...
- 自定义滚动条 - mCustomScrollbar
项目中需要使用自定义滚动条,但是试用了很多都功能不够全,今天发现一个比较全而且用法很简单的 -- mCustomScrollbar http://manos.malihu.gr/jquery-cust ...
- Flex:自定义滚动条样式/隐藏上下箭头
Flex组件自定义滚动条的实现 .scrollBar{ downArrowUpSkin:Embed(source="img/mainLeftScrollBar/bar_bottom.png& ...
- javascript自定义滚动条插件,几行代码的事儿
在实际项目中,经常由于浏览器自带的滚动条样式太戳,而且在各个浏览器中显示不一样,所以我们不得不去实现自定义的滚动条,今天我就用最少的代码实现了一个自定义滚动条,代码量区区只有几十行,使用起来也非常方便 ...
随机推荐
- 【JVM】关于OOM的二三事
组织架构 严格来说,StackOverflowError和OutOfMemoryError都属于错误,而不是异常. java.lang.StackOverflowError public class ...
- MySQL 高级—— 锁机制
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.锁的概述 1.锁的定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除传统的计 ...
- ASP.NET防止自己网站的资源被盗(通过IHttpHandler 带样例说明)
我这里用的图片被盗举例子 一个正常的网页 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind ...
- (Java实现) 洛谷 P1781 宇宙总统
题目背景 宇宙总统竞选 题目描述 地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有n个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统. 输入输出格式 输入格式: pr ...
- Java实现 LeetCode 336 回文对
336. 回文对 给定一组唯一的单词, 找出所有不同 的索引对(i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串. 示例 1: 输入: ["abc ...
- Java实现 LeetCode 136 只出现一次的数字
136. 只出现一次的数字 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现 ...
- Java实现回文判断
1 问题描述 给定一个字符串,如何判断这个字符串是否是回文串? 所谓回文串,是指正读和反读都一样的字符串,如madam.我爱我等. 2 解决方案 解决上述问题,有两种方法可供参考: (1)从字符串两头 ...
- Java实现 洛谷 P1618 三连击(升级版)
import java.util.Arrays; import java.util.Scanner; public class Main { private static Scanner cin; p ...
- 如何将自己在github写的android library开源,让大家依赖使用
编写library并上传至github后,让别人可以通过gradle的方式添加依赖 http://www.jianshu.com/p/9aedfd749cec
- MYSQL 实现ROWNO功能
select tt.rowno from( select (@rownum:=@rownum+1) as rowno, t.id from news t ,(select (@rownum : ...

