如何在ListView之外对齐滚动条?

问题描述 投票:0回答:1

enter image description here

所以,问题出在我的 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,
          );
  }
}
flutter position scrollbar
1个回答
0
投票

您可以覆盖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;
}
© www.soinside.com 2019 - 2024. All rights reserved.