所以,问题出在我的 RawScrollBar 上。将它放在 ListView 内没有问题,但我需要它位于所有容器之外。我可以像图片一样将其放在外面,但似乎无法将其放在我需要的底部。 那么,有什么方法可以改变我的 RawScrollBar 的位置吗?
补充信息:1、2、3号图片上是容器,ListView本身是容器内的表格。它很容易滚动,并且滚动条确实显示滚动。问题只是一个立场。我用红色强调了 RawScrollBar 刚刚卡住的位置,但我需要它来代替问号位置。
这是我的简短主要代码,如果需要,我会尝试提供更多内容:
Widget build(BuildContext context) {
return MyScrollbar (
controller: scrollCtrl,
child: GetBuilder<...>(
tag: controller!.tag,
init: controller!,
builder: (c) => Container(
margin: const EdgeInsets.all(24),
child: Column(
children: [
Container(...),
const SizedBox(height: 24),
Expanded(
child: _Body(..., scrollController), //another container inside this Body, and ListView inside its container
),
],
),
),
),
);
}
我的滚动条小部件:
class MyScrollbar extends StatelessWidget {
final ScrollController controller;
final Widget child;
const MyScrollbar ({
required this.controller,
required this.child,
});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(right: 6),
child: RawScrollbar(
controller: controller,
radius: const Radius.circular(12),
trackRadius: const Radius.circular(12),
thumbVisibility: true,
trackVisibility: true,
scrollbarOrientation: ScrollbarOrientation.right,
child: child,
);
}
}
您可以覆盖ScrollConfiguration并将scrollBar设置为false。然后使用
NotificationListener
+ AnimatedBuilder
或 CustomPaint 作为滚动条。
FIXME:目前我正在下降以获得(MaxScrollExtent/viewPortHeight)的比率
如果我将来做了任何更新,你可以在gist 46f502e70de001e159b6dcf2e7a0a39a
中找到它class MyListView extends StatefulWidget {
const MyListView({super.key});
@override
State<MyListView> createState() => _MyListViewState();
}
class _MyListViewState extends State<MyListView> {
final ScrollController controller = ScrollController();
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: ScrollConfiguration(
behavior: ScrollBehavior().copyWith(scrollbars: false),
child: Column(
children: [
Container(
height: 200,
width: double.infinity,
color: Colors.cyan,
),
Expanded(
child: ListView.builder(
controller: controller,
itemCount: 23,
itemBuilder: (context, index) => ListTile(
tileColor: index.isEven ? Colors.red : Colors.white,
),
),
)
],
),
),
),
const SizedBox(width: 48),
SizedBox(
height: double.infinity,
width: 48,
child: CustomPaint(
painter: MyScrollBarPainter(controller),
),
)
],
);
}
}
class MyScrollBarPainter extends CustomPainter {
const MyScrollBarPainter(this.controller) : super(repaint: controller);
final ScrollController controller;
@override
void paint(Canvas canvas, Size size) {
if (controller.hasClients == false) return;
///FIXME: currently I am falling to get the ratio of (MaxScrollExtent/viewPortHeight)
final barHeight = controller.position.maxScrollExtent / 10;
final t = controller.offset / controller.position.maxScrollExtent;
final double top = lerpDouble(0, size.height - barHeight, t) ?? 1;
debugPrint("t $t height $barHeight");
final rrect = RRect.fromRectAndRadius(
Rect.fromLTWH(0, top, 10, barHeight),
Radius.circular(12),
);
canvas.drawRRect(rrect, Paint()..color = Colors.green);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}