Futter:嵌套滚动条和窗口水平滚动不起作用



关于实现特定效果,我有两个问题/疑问。

  1. 我想达到这种效果,我已经实现了一个解决方案(两个说实话),但他们都不工作。详情如下:

    • 这是我实现的第一个解决方案的代码,在这里你可以看到两个滚动条,但是当水平滚动条时(不是通过触控板,因为触控板水平滚动不起作用),垂直滚动条也被滚动走了。

      class ScrollPanWidget extends StatefulWidget {
      final Widget child;
      const ScrollPanWidget({Key? key, required this.child}) : super(key: key);
      @override
      State<ScrollPanWidget> createState() => _ScrollPanWidgetState();
      }
      class _ScrollPanWidgetState extends State<ScrollPanWidget> {
      late ScrollController verticalController, horizontalController;
      @override
      void initState() {
      super.initState();
      verticalController = ScrollController();
      horizontalController = ScrollController();
      }
      @override
      Widget build(BuildContext context) {
      return _HorizontalPart(
      horizontalController: horizontalController,
      child: _VerticalPart(
      verticalController: verticalController, child: widget.child),
      );
      }
      }
      class _HorizontalPart extends StatelessWidget {
      final ScrollController horizontalController;
      final Widget child;
      const _HorizontalPart(
      {Key? key, required this.horizontalController, required this.child})
      : super(key: key);
      @override
      Widget build(BuildContext context) {
      return RawScrollbar(
      thumbVisibility: true,
      trackColor: Colors.grey,
      thumbColor: Theme.of(context).colorScheme.primary.withOpacity(0.8),
      trackBorderColor: Colors.blueGrey,
      controller: horizontalController,
      scrollbarOrientation: ScrollbarOrientation.top,
      child: SingleChildScrollView(
      controller: horizontalController,
      scrollDirection: Axis.horizontal,
      child: child,
      ),
      );
      }
      }
      class _VerticalPart extends StatelessWidget {
      final ScrollController verticalController;
      final Widget child;
      const _VerticalPart(
      {Key? key, required this.verticalController, required this.child})
      : super(key: key);
      @override
      Widget build(BuildContext context) {
      return RawScrollbar(
      thumbVisibility: true,
      trackColor: Colors.grey,
      thumbColor: Theme.of(context).colorScheme.primary.withOpacity(0.8),
      trackBorderColor: Colors.blueGrey,
      scrollbarOrientation: ScrollbarOrientation.left,
      controller: verticalController,
      child: SingleChildScrollView(
      controller: verticalController,
      scrollDirection: Axis.vertical,
      child: child,
      ),
      );
      }
      }
      
    <代码>
    
  • 这是我实现的第二个解决方案,您可以用ScrollPanWidget的构建方法替换它。在这个解决方案中,其中一个滚动条没有显示。图片在这里
import 'package:flutter/material.dart';

class NestedScrollbarsNotShowingApp extends StatefulWidget {
const NestedScrollbarsNotShowingApp({Key? key}) : super(key: key);
@override
State<NestedScrollbarsNotShowingApp> createState() =>
_NestedScrollbarsNotShowingAppState();
}

class _NestedScrollbarsNotShowingAppState
extends State<NestedScrollbarsNotShowingApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: const Text('Classic Material App Bar'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: ScrollPanWidget(
child: Container(
color: Colors.red,
height: 1200,
width: 1500,
),
),
)),
),
);
}
}

class ScrollPanWidget extends StatefulWidget {
final Widget child;
const ScrollPanWidget({Key? key, required this.child}) : super(key: key);

@override
State<ScrollPanWidget> createState() => _ScrollPanWidgetState();
}

class _ScrollPanWidgetState extends State<ScrollPanWidget> {
late ScrollController verticalController, horizontalController;

@override
void initState() {
super.initState();
verticalController = ScrollController();
horizontalController = ScrollController();
}

@override
Widget build(BuildContext context) {
return _HorizontalPart(
horizontalController: horizontalController,
child: _VerticalPart(
verticalController: verticalController, child: widget.child),
);
}

solutionThatDoesntWork() {
return Stack(
children: [
SingleChildScrollView(
controller: verticalController,
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
controller: horizontalController,
scrollDirection: Axis.horizontal,
child: widget.child,
),
),
RawScrollbar(
thumbVisibility: true,
trackColor: Colors.grey,
thumbColor: Theme.of(context).colorScheme.primary.withOpacity(0.8),
trackBorderColor: Colors.blueGrey,
controller: verticalController,
scrollbarOrientation: ScrollbarOrientation.right,
child: RawScrollbar(
thumbVisibility: true,
trackColor: Colors.grey,
thumbColor: Theme.of(context).colorScheme.primary.withOpacity(0.8),
trackBorderColor: Colors.blueGrey,
scrollbarOrientation: ScrollbarOrientation.bottom,
controller: horizontalController,
child: Column(
mainAxisSize: MainAxisSize.max,
children: const [],
),
),
),
],
);
}
}

class _HorizontalPart extends StatelessWidget {
final ScrollController horizontalController;
final Widget child;
const _HorizontalPart(
{Key? key, required this.horizontalController, required this.child})
: super(key: key);

@override
Widget build(BuildContext context) {
return RawScrollbar(
thumbVisibility: true,
trackColor: Colors.grey,
thumbColor: Theme.of(context).colorScheme.primary.withOpacity(0.8),
trackBorderColor: Colors.blueGrey,
controller: horizontalController,
scrollbarOrientation: ScrollbarOrientation.top,
child: SingleChildScrollView(
controller: horizontalController,
scrollDirection: Axis.horizontal,
child: child,
),
);
}
}

class _VerticalPart extends StatelessWidget {
final ScrollController verticalController;
final Widget child;
const _VerticalPart(
{Key? key, required this.verticalController, required this.child})
: super(key: key);

@override
Widget build(BuildContext context) {
return RawScrollbar(
thumbVisibility: true,
trackColor: Colors.grey,
thumbColor: Theme.of(context).colorScheme.primary.withOpacity(0.8),
trackBorderColor: Colors.blueGrey,
scrollbarOrientation: ScrollbarOrientation.left,
controller: verticalController,
child: SingleChildScrollView(
controller: verticalController,
scrollDirection: Axis.vertical,
child: child,
),
);
}
}

如果我的解决方案不能工作,你能指出一个方向,我应该为实现相同的工作(不要求实际的代码,因此这不是一个广泛的问题,按照指导方针)。

  1. 在窗口上,当水平滚动时,Flutter会改变小部件的焦点,而不是将滚动事件传递给水平滚动视图。在这方面有什么可以做的吗?在Flutter Web上未观察到此行为。

  2. 另外,我确实想让小部件响应触摸和鼠标输入进行平移(鼠标输入不是必要的,因为它们可以被忽略,以便滚动小部件acc到第2点)。所以你建议使用Stackimport 'package:dual_scroll/dual_scroll.dart';的组合,并将子小部件放置在定位小部件中进行平移吗?或者是更好地使用手势检测器和滚动控制器平移子窗口小部件?

提前感谢您的帮助!

完整代码:

return DualScroll(
verticalScrollbar: ScrollBar.defaultScrollBar(),
horizontalScrollbar: ScrollBar.defaultScrollBar(),
child: Container(), /* Your child widget here*/
);

因此,我实际上自己实现了解决方案,并将其作为pub包dual_scroll发布。你可以这样直接使用它:

从导入包

开始CC_4

通过包装Widget来使用。你想要通过以下方式滚动:

PP_5高级用法请参见pub.dev

最新更新