![](https://img.haomeiwen.com/i4163152/decce80391995e98.png)
![](https://img.haomeiwen.com/i4163152/7f54d4be087613c4.png)
整个页面是外层滑动,然后“设定结果”中的内容是内层滑动。当我们在内部滑动区域之外,滑动的都是外部区域。
当我们在内部区域滑动的时候,需要自己处理滑动事件
- 往上滑动的时候先整体往上滑动,直到外部到底。再次滑动才是滑动内部区域
- 往下滑动的时候先滑动内部区域,直到内部到头,再次滑动才是滑动外部区域
- 自己处理事件滑动感觉很卡,需要添加惯性滑动
- 当处于内部中间开始滑动的时候,惯性滑动不会传导到外部滑动区域
滑动处理核心代码如下:
customScrollController是外部滑动的控制器。
double scrollStartPosition = 0;
double outerScrollStartPosition = 0;
...
return IndexedStack(
index: value,
children: answers.map((e) {
ScrollController inspirationController = ScrollController();
return SingleChildScrollView(
controller: scrollController ?? inspirationController,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.only(left: 14, right: 14, top: 12).csp2,
child: GestureDetector(
onVerticalDragStart: (DragStartDetails details) {
scrollStartPosition = (scrollController ?? inspirationController).position.pixels;
outerScrollStartPosition = customScrollController.position.pixels;
debugPrint(" DragStartDetails scrollStartPosition $scrollStartPosition outerScrollStartPosition $outerScrollStartPosition");
},
onVerticalDragEnd: (DragEndDetails details) {
///惯性处理
debugPrint("DragEndDetails ${scrollController ?? inspirationController.position.pixels} details.velocity ${details.velocity}");
bool isOver = (scrollController ?? inspirationController).position.pixels - details.velocity.pixelsPerSecond.dy * 0.15 > (scrollController ?? inspirationController).position.maxScrollExtent;
bool isHead = (scrollController ?? inspirationController).position.pixels - details.velocity.pixelsPerSecond.dy * 0.15 < 0;
bool isHeadInertia = scrollStartPosition <= 0;
bool isOuterOverInertia = outerScrollStartPosition >= customScrollController.position.maxScrollExtent;
debugPrint("DragEndDetails isOver $isOver isHead $isHead scrollStartPosition $scrollStartPosition outerScrollStartPosition $outerScrollStartPosition");
if (details.velocity.pixelsPerSecond.dy < 0) {
///往上滑动 惯性滚动外部区域
bool isOuterOver1 = customScrollController.position.pixels - details.velocity.pixelsPerSecond.dy * 0.15 > customScrollController.position.maxScrollExtent;
customScrollController.animateTo(isOuterOver1 ? customScrollController.position.maxScrollExtent : customScrollController.position.pixels - details.velocity.pixelsPerSecond.dy * 0.3, duration: const Duration(milliseconds: 300), curve: Curves.decelerate);
///如果滑动到底部了,继续给里面一个惯性
if (isOuterOverInertia) {
(scrollController ?? inspirationController).animateTo(isOver ? (scrollController ?? inspirationController).position.maxScrollExtent : (scrollController ?? inspirationController).position.pixels - details.velocity.pixelsPerSecond.dy * 0.15,
duration: const Duration(milliseconds: 300), curve: Curves.decelerate);
}
} else {
///往下滑动 惯性滑动里面
(scrollController ?? inspirationController).animateTo(isHead ? 0 : (scrollController ?? inspirationController).position.pixels - details.velocity.pixelsPerSecond.dy * 0.15, duration: const Duration(milliseconds: 300), curve: Curves.decelerate);
///如果已经到头了,继续给外部一个惯性
if (isHeadInertia) {
bool isOuterHead1 = customScrollController.position.pixels - details.velocity.pixelsPerSecond.dy * 0.15 < 0;
customScrollController.animateTo(isOuterHead1 ? 0 : customScrollController.position.pixels - details.velocity.pixelsPerSecond.dy * 0.3, duration: const Duration(milliseconds: 300), curve: Curves.decelerate);
}
}
},
onVerticalDragUpdate: (DragUpdateDetails details) {
debugPrint("details.delta.dy ${details.delta.dy} scrollController!.position.pixels :${(scrollController ?? inspirationController).position.pixels} scrollController!.position.maxScrollExtent ${(scrollController ?? inspirationController).position.maxScrollExtent}");
///判断滑动方向: 如果是往上滑动,按照之前的处理。 如往下滑动,需要先滑动外面,在滑动里面
bool isOver = (scrollController ?? inspirationController).position.pixels - details.delta.dy > (scrollController ?? inspirationController).position.maxScrollExtent;
bool isHead = (scrollController ?? inspirationController).position.pixels - details.delta.dy < 0;
if (details.delta.dy < 0) {
///往上滑动
bool isOuterOver = customScrollController.position.pixels - details.delta.dy > customScrollController.position.maxScrollExtent;
customScrollController.jumpTo(isOuterOver ? customScrollController.position.maxScrollExtent : customScrollController.position.pixels - details.delta.dy);
if (isOuterOver) {
(scrollController ?? inspirationController).jumpTo(isOver ? (scrollController ?? inspirationController).position.maxScrollExtent : (scrollController ?? inspirationController).position.pixels - details.delta.dy);
}
} else {
///往下滑动
(scrollController ?? inspirationController).jumpTo(isHead ? 0 : (scrollController ?? inspirationController).position.pixels - details.delta.dy);
///滑到头了,就滑动外面
if ((scrollController ?? inspirationController).position.pixels <= 0) {
bool isOver = customScrollController.position.pixels - details.delta.dy < 0;
customScrollController.jumpTo(isOver ? 0 : customScrollController.position.pixels - details.delta.dy);
}
}
},
child: SelectionArea(
child: SizedBox(
width: 1.sh - 60.csp2,
// // height: cacheMap[op.answerHeightKey],
// color: Colors.red,
child: Text(
e,
style: AIGenModelEx.style.copyWith(color: context.colorTheme.textFF6A3000),
// strutStyle: const StrutStyle(height: 1.2),
),
),
),
),
);
}).toList());
网友评论