Flutter滑动冲突处理——GestureDetector嵌套ListView

哈喽,我是老刘

几年前分享了一篇GestureDetector嵌套ListView的文章

Flutter多控件滑动事件联动(滑动冲突处理) - 知乎 (zhihu.com)

由于文章中只给出了关键部位的代码,另外使用的技术也偏底层

所以很多同学私信我要完整的源码

这里把原先的方案整理一下,另外也给出完整的代码供大家参考

我们先一点一点来看这个问题

滑动关闭组件

首先大家一定在各种App中见过这个滑动关闭组件

就是手指向下滑动,组件跟随手指移动

手指抬起后组件滑出屏幕

我们先来实现这个组件,然后来讨论一下如果组件中的内容时一个ListView,要怎么处理

如果这个组件的内容时固定内容,不是ListView这样的可滚动组件

实现起来其实很简单

我这里直接放源码

import 'package:flutter/material.dart';

class CloseOnSwipeDownWidget extends StatefulWidget {
  final Widget child;

  const CloseOnSwipeDownWidget({
    Key? key,
    required this.child,
  }) : super(key: key);

  @override
  CloseOnSwipeDownWidgetState createState() => CloseOnSwipeDownWidgetState();
}

class CloseOnSwipeDownWidgetState extends State
    with TickerProviderStateMixin {
  double yOffset = 0.0;
  double initialPosition = 0.0;
  bool isAnimatingOut = false;
  int animTime = 0;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onVerticalDragDown: (details) {
        initialPosition = details.globalPosition.dy;
      },
      onVerticalDragUpdate: (details) {
        double updatedPosition = details.globalPosition.dy;
        double deltaY = updatedPosition - initialPosition;

        animTime = 0;

        setState(() {
          yOffset = yOffset + deltaY;
          initialPosition = updatedPosition;
        });
      },
      onVerticalDragEnd: (details) {
        animTime = 300;

        if (yOffset > 200) {
          // 触发滑出动画
          _startSlideOutAnimation();
        } else {
          // 触发返回原始位置的动画
          _startReturnToOriginalPositionAnimation();
        }
      },
      child: Stack(
        children: [
          AnimatedPositioned(  // 组件跟随手指位移,以及抬起手指后组件移动动画
            duration: Duration(milliseconds: animTime),
            curve: Curves.easeInOut,
            top: yOffset,
            left: 0,
            right: 0,
            child: widget.child,
            onEnd: () {
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值