Flutter触摸事件之仿购物车加减按钮控件,实现点击长按

实现了点击和长按都可以的效果
在这里插入图片描述
这里需要注意的几个点
首先Flutter没有Thread的概念,之前在Android中我们是可以通过控制线程去实现长按一秒内加10个数字这样
其次Flutter的长按事件和Android中的一样 ,onLongpress(),长按的时候它只会调用一次,没有持续的监听效果。在Android中我们可以通过去监听按钮的onTouch事件,Action,up,down,move等去实现长按监听。在Flutter中依然如此:GestureDetector

什么是GestureDetector

Property/Callback	Description
onTapDown	用户每次和屏幕交互时都会被调用
onTapUp	用户停止触摸屏幕时触发
onTap	短暂触摸屏幕时触发
onTapCancel	用户触摸了屏幕,但是没有完成Tap的动作时触发
onDoubleTap	用户在短时间内触摸了屏幕两次
onLongPress	用户触摸屏幕时间超过500ms时触发
onVerticalDragDown	当一个触摸点开始跟屏幕交互,同时在垂直方向上移动时触发
onVerticalDragStart	当触摸点开始在垂直方向上移动时触发
onVerticalDragUpdate	屏幕上的触摸点位置每次改变时,都会触发这个回调
onVerticalDragEnd	当用户停止移动,这个拖拽操作就被认为是完成了,就会触发这个回调
onVerticalDragCancel	用户突然停止拖拽时触发
onHorizontalDragDown	当一个触摸点开始跟屏幕交互,同时在水平方向上移动时触发
onHorizontalDragStart	当触摸点开始在水平方向上移动时触发
onHorizontalDragUpdate	屏幕上的触摸点位置每次改变时,都会触发这个回调
onHorizontalDragEnd	水平拖拽结束时触发
onHorizontalDragCancel	onHorizontalDragDown没有成功完成时触发
onPanDown	当触摸点开始跟屏幕交互时触发
onPanStart	当触摸点开始移动时触发
onPanUpdate	屏幕上的触摸点位置每次改变时,都会触发这个回调
onPanEnd	pan操作完成时触发
onScaleStart	触摸点开始跟屏幕交互时触发,同时会建立一个焦点为1.0
onScaleUpdate	跟屏幕交互时触发,同时会标示一个新的焦点
onScaleEnd	触摸点不再跟屏幕有任何交互,同时也表示这个scale手势完成

下面直接上代码吧!!!

import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '数字测试 Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: '数字测试'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  ///数字
  int num = 0;
  Timer timer;

  ///按钮
  Widget btn() {
    return Container(
      width: 300,
      height: 50,
      decoration: new BoxDecoration(
        shape: BoxShape.rectangle,
        borderRadius: BorderRadius.circular(5),
        border: Border.all(color: Color(0x33333333)),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Padding(
            padding: EdgeInsets.only(left: 20),
            child: Align(
              child: Text(
                '$num',
                style: TextStyle(color: Color(0xff333333), fontSize: 20),
              ),
            ),
          ),
          Row(
            children: <Widget>[
              new GestureDetector(
                child: Container(
                  width: 50,
                  height: 30,
                  child: Icon(Icons.remove),
                ),
                //不写的话点击起来不流畅
                onTap: () {
                  setState(() {
                    if (num <= 0) {
                      return;
                    }
                    num--;
                  });
                },
                onTapDown: (e) {
                  if (timer != null) {
                    timer.cancel();
                  }
                  if (num <= 0) {
                    return;
                  }
                  // 这里面的触发时间可以自己定义
                  timer = new Timer.periodic(Duration(milliseconds: 100), (e) {
                    setState(() {
                      if (num <= 0) {
                        return;
                      }
                      num--;
                    });
                  });
                },
                onTapUp: (e) {
                  if (timer != null) {
                    timer.cancel();
                  }
                },
                // 这里防止长按没有抬起手指,而move到了别处,会继续 --
                onTapCancel: () {
                  if (timer != null) {
                    timer.cancel();
                  }
                },
              ),
              new GestureDetector(
                child: Container(
                  width: 50,
                  height: 30,
                  child: Icon(Icons.add),
                ),
                onTap: () {
                  setState(() {
                    if (num >= 999999999) {
                      return;
                    }
                    num++;
                  });
                },
                onTapDown: (e) {
                  if (timer != null) {
                    timer.cancel();
                  }
                  if (num >= 999999999) {
                    return;
                  }
                  timer = new Timer.periodic(Duration(milliseconds: 100), (e) {
                    setState(() {
                      if (num >= 999999999) {
                        return;
                      }
                      num++;
                    });
                  });
                },
                onTapUp: (e) {
                  if (timer != null) {
                    timer.cancel();
                  }
                },
                onTapCancel: () {
                  if (timer != null) {
                    timer.cancel();
                  }
                },
              ),
            ],
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: btn(),
      ),
    );
  }
}

其实来来回回就是用了GestureDetector,还有Flutter的Timer.periodic 定时器
以上over

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值