关于实现特定效果,我有两个问题/疑问。
-
我想达到这种效果,我已经实现了一个解决方案(两个说实话),但他们都不工作。详情如下:
-
这是我实现的第一个解决方案的代码,在这里你可以看到两个滚动条,但是当水平滚动条时(不是通过触控板,因为触控板水平滚动不起作用),垂直滚动条也被滚动走了。
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,
),
);
}
}
如果我的解决方案不能工作,你能指出一个方向,我应该为实现相同的工作(不要求实际的代码,因此这不是一个广泛的问题,按照指导方针)。
在窗口上,当水平滚动时,Flutter会改变小部件的焦点,而不是将滚动事件传递给水平滚动视图。在这方面有什么可以做的吗?在Flutter Web上未观察到此行为。
另外,我确实想让小部件响应触摸和鼠标输入进行平移(鼠标输入不是必要的,因为它们可以被忽略,以便滚动小部件acc到第2点)。所以你建议使用
Stack
和import '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