import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class HiFixedScrollbar extends StatefulWidget { final Widget child; final ScrollController controller; final bool isShowScrollbar; /// 距离右边的间距(默认 18) final double right; /// 滚动条宽度 final double thickness; /// 滚动条颜色(默认白色 30%) final Color thumbColor; /// 背景轨道颜色(默认白色 15%) final Color trackColor; /// 滚动条固定高度(默认 50) final double thumbHeight; const HiFixedScrollbar({ super.key, required this.child, required this.controller, this.right = 18, this.isShowScrollbar = true, this.thickness = 5, this.thumbHeight = 50, this.thumbColor = const Color.fromRGBO(255, 255, 255, 0.3), this.trackColor = const Color.fromRGBO(255, 255, 255, 0.15), }); @override State createState() => _HiFixedScrollbarState(); } class _HiFixedScrollbarState extends State { double _thumbOffset = 0.0; @override void initState() { super.initState(); widget.controller.addListener(_updateThumbPosition); } void _updateThumbPosition() { if (!mounted) return; final position = widget.controller.position; if (!position.hasPixels || !position.hasContentDimensions) return; final maxScrollExtent = position.maxScrollExtent; final offset = position.pixels; final viewport = position.viewportDimension; // ✅ 固定高度滚动条,只根据滚动比例移动位置 final trackHeight = viewport - widget.thumbHeight; final scrollRatio = maxScrollExtent == 0 ? 0 : offset / maxScrollExtent; setState(() { _thumbOffset = (trackHeight * scrollRatio).clamp(0, trackHeight); }); } @override void dispose() { widget.controller.removeListener(_updateThumbPosition); super.dispose(); } @override Widget build(BuildContext context) { return LayoutBuilder( builder: (_, constraints) { return Stack( children: [ // 滚动内容 widget.child, if(widget.isShowScrollbar) ...[ // 滚动条轨道 Positioned( right: widget.right.w, top: 0, bottom: 0, child: Container( width: widget.thickness.w, decoration: BoxDecoration( color: widget.trackColor, borderRadius: BorderRadius.circular(4), ), ), ), // 滚动条拇指 Positioned( right: widget.right.w, top: _thumbOffset, child: Container( width: widget.thickness.w, height: widget.thumbHeight, decoration: BoxDecoration( color: widget.thumbColor, borderRadius: BorderRadius.circular(4), ), ), ), ] ], ); }, ); } }