Flutter 嵌套滑动事件处理

2023-10-07  本文已影响0人  旺仔_100
image.png
image.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());
上一篇 下一篇

猜你喜欢

热点阅读