前语

flutter 中,除了运用 TextButton 之外,运用最多的便是GestureDetector手势了,这篇文章就简单介绍下GestureDetector手势

下面是手势中常常合作运用的两个办法

//获取屏幕的size信息
MediaQuery.of(context).size
//获取当时组件size信息,组件默许持有,不必从build中传递
context.size

获取当时组件的偏移量,能够通过组件的context获取RenderBox,能够用来动态获取更多必要的核算信息

组件烘托完结之后,能够通过组价你的context参数,直接获取组件的偏移量
RenderBox box = context.findRenderObject() as RenderBox;
final local = box.localToGlobal(Offset.zero);
print(local);

GestureDetector

手势生效规模,默许为包裹子视图规模内(留意:子视图一般默许会填充,再加上居中作用简单误认为点击区间出问题),且默许一切点击事情是能够持续冒泡,持续向下反应的,即除了顶部视图呼应,被挡住的视图也会相应点击事情

GestureDetector(
    onTap: () {
        //默许的点击事情,和textbutton相似,一般运用这个,抬起时生效
    },
    onTapDown: (TapDownDetails details)  {
        //点击后立即触发,特殊场景运用,一般合作tap的其他来设置点击作用
        //TapDownDetails中有点击的方位等信息
    },
    onTapCancel: () {
        //用于点击事情的取消操作,一般用于合作上面你的办法定制点击事情
    },
    onLongPress: () {
        //长按触发事情,一般用于预览界面不适合添加额外按钮,添加长按手势触发躺床才做
    },
    onDoubleTap: () {
        //双击触发事情,由时间短的接连单机事情封装而成,一般用于web端操作,移动端罕见
    },
    onVerticalDragUpdate: (DragUpdateDetails details) {
      //拖拽更新,pan实际走的也是这个,不信看看参数
      //世界坐标details.globalPosition
      //本地坐标details.localPosition
      onUpdate(details.localPosition.dy);
    },
    onVerticalDragDown: (DragDownDetails details) {
      //拖拽动作点击时触发一次,假如点击时需求更新方位等信息,能够调用
    },
    onVerticalDragStart: (DragStartDetails details) {
        //拖拽动作开始时触发,实际上和down办法挑选一个即可
    },
    onVerticalDragEnd: (DragEndDetails details) {
      //拖拽完毕,能够处理相关事情的结尾工作,或者康复
    },
    //他们三个也是和拖拽逻辑一模相同,只不过换一个姓名,参数类型都相同
    //应该是对不同端的开发习惯的支持
    onPanDown: (DragDownDetails details) {},
    onPanEnd: (DragEndDetails details) {},
    onVerticalDragStart: (DragStartDetails details) {},
    onPanUpdate: (DragUpdateDetails details) {},
    child: Container(
        color: Colors.black26,
        width: 20,
        child: const Text("点击吧"),
    ),
),

阻挠事情冒泡

假如点击了某个视图,想阻挠其向下冒泡,能够运用 IgnorePointer 来包裹呼应模块即可

一般情况下运用的onTap,是默许阻挠冒泡的,而 onTapDown,则没有阻挠,能够根据需求添加

const IgnorePointer(
    child: GestureDetector(child: const Text('点击我,底部的就没有反应了')),
),

阻挠冒泡场景模拟:一个ListView.builder,默许item的点击事情进入item事例概况,item中有一个按钮,点击后能够检查相似内容,点击后不进入概况页,因此需求阻挠事情的冒泡,那样里边的按钮运用 IgnorePointer 包裹即可

例如:

下面的就会呈现手势抵触,能够运用 IgnorePointer包裹里边的 GestureDetector(实际上拖拽等手势,也可能会呈现不同层级的呼应抵触问题)

//默许手势抵触事例
ListView.builder(
  itemCount: 20,
  itemBuilder: (BuildContext context, int index) {
    return GestureDetector(
      onTapDown: (TapDownDetails details) {
        print("底部$index");
      },
      child: Container(
        height: 80,
        color: Colors.yellow,
        alignment: Alignment.center,
        child: GestureDetector(
          onTapDown: (TapDownDetails details) {
            print("顶部$index");
          },
          child: Text("哈哈哈$index"),
          ),
        )
    );
  },
);
//解决方案
ListView.builder(
  itemCount: 20,
  itemBuilder: (BuildContext context, int index) {
    return GestureDetector(
      onTapDown: (TapDownDetails details) {
        print("底部$index");
      },
      child: Container(
        height: 80,
        color: Colors.yellow,
        alignment: Alignment.center,
        child: IgnorePointer(
          child: GestureDetector(
            onTapDown: (TapDownDetails details) {
              print("顶部$index");
            },
            child: Text("哈哈哈$index"),
          ),
        ),
      ),
    );
  },
);

最后

能够点赞收藏,今后用到的时分,能够打开观看一下