• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android触摸事件(二)-TouchUtils,触摸辅助工具类

Android触摸事件(二)-TouchUtils,触摸辅助工具类

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android 点击事件,android onclick事件,android ontouch事件,android 双击事件,android 触摸事件等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android触摸事件(二)-TouchUtils,触摸辅助工具类


概述

此类的主要作用是封装了一些触摸事件需要常用的操作,只需要实现简单的接口即可以使用.实现操作如下:

界面拖动(基于单点触摸的移动事件) 界面的缩放(基于两点触摸的移动事件)

此类只是一个辅助工具类,并不是必须的也不需要继承此类就可以使用.

此类基于AbsTouchEventHandle类回调的事件基础,需要AbsTouchEventHandle先处理基本的触摸事件,再通过此辅助类实现拖动的操作

不管是拖动还是缩放,本质是基于坐标数据的,所以坐标数据的记录是必然的,因此需要记录的坐标数据如下:

//单点触摸拖动
//按下事件的坐标
private float mDownX = 0f;
private float mDownY = 0f;
//抬起事件的坐标
private float mUpX = 0f;
private float mUpY = 0f;

//多点触摸缩放
//多点触控缩放按下坐标
private float mScaleFirstDownX = 0f;
private float mScaleFirstDownY = 0f;
private float mScaleSecondDownX = 0f;
private float mScaleSecondDownY = 0f;
//多点触摸缩放抬起的坐标
private float mScaleFirstUpX = 0f;
private float mScaleFirstUpY = 0f;
private float mScaleSecondUpX = 0f;
private float mScaleSecondUpY = 0f;

关于拖动

原理

拖动的原理比较好理解,主要是通过跟随触摸点坐标的变化而达到拖动的效果

实现拖动的方式有多种,这里使用的方式为原数据与变动数据分开操作的方式.因此需要保存界面偏移量的变量.

//记录X轴方向的偏移量
float mDrawOffsetX;
//记录Y轴方向的偏移量
float mDrawOffsetY;

实现过程

关键变量定义

移动偏移量:MOVE 事件结束后新坐标相对于 DOWN 事件时坐标的偏移量
原始偏移量:界面在 DOWN 事件发生之前已经存在的偏移量
实际偏移量:以界面最初加载的状态为原始状态,任何时候对原始状态的偏移量都为界面当前的实际偏移量,原始偏移量即为上一次的实际偏移量(产生的移动偏移量将使此值变化)

每一次ACTION_MOVE事件会造成界面偏移,产生一次偏移量.在ACTION_MOVE事件结束后将本次产生的移动偏移量与原始偏移量合并,生成新的界面偏移量,此偏移量即为界面实际的偏移量.
具体过程如下:

单点按下时,记录当前触摸点坐标数据 downX,downY 单点移动时,记录每一次移动后的新触摸点的坐标数据 moveX,moveY 进入拖动界面偏移量计算工作
计算移动后位置与按下时位置的偏移量 moveX-downX,moveY-downY 计算新的界面实际偏移量(原始偏移量+移动偏移量) 保存新的实际偏移量即可 重绘界面

整个拖动过程改变的只是界面的偏移变量,界面原始的任何坐标数据不会被改变,因此绘制界面是实际的绘制方式应该是:

//设绘制元素的原始坐标为 X,Y; 实际偏移量为 offsetX,offsetY
//绘制该元素
draw(X+offsetX, Y+offsetY);

由此可确定,偏移量是存在正负值的,正负值表示相反方向的偏移;而 mBDrawOffsetX与mDrawOffsetY原始值必定为0


事件处理回调

理论上界面的拖动是无任何限制的,但是在实际的操作中,存在一些实际的要求导致界面的拖动范围存在限制.界面的拖动是实际上是为了显示不在屏幕中的其它元素,当拖动超过一定范围时,屏幕中将不存在任何元素,偏移范围已经远远超过元素所在的坐标位置,这是没有意义的.

在界面拖动时,将提供对应的回调接口,用以确定界面是否可以拖动.当界面确认可以拖动时,才进行重绘工作,当界面不允许拖动时,只会保留最后一次ACTION_MOVE事件中可重绘的界面.

对外的回调接口如下:

/**
 * 移动事件处理接口
 */
public interface IMoveEvent {

    /**
     * 是否可以实现X轴的移动
     *
     * @param moveDistanceX 当次X轴的移动距离(可正可负)
     * @param newOffsetX    新的X轴偏移量(若允许移动的情况下,此值实际上即为上一次偏移量加上当次的移动距离)
     * @return
     */
    public abstract boolean isCanMovedOnX(float moveDistanceX, float newOffsetX);

    /**
     * 是否可以实现Y轴的移动
     *
     * @param moveDistacneY 当次Y轴的移动距离(可正可负)
     * @param newOffsetY    新的Y轴偏移量(若允许移动的情况下,此值实际上即为上一次偏移量加上当次的移动距离)
     * @return
     */
    public abstract boolean isCanMovedOnY(float moveDistacneY, float newOffsetY);

    /**
     * 移动事件
     *
     * @param suggestEventAction 建议处理的事件,值可能为{@link MotionEvent#ACTION_MOVE},{@link MotionEvent#ACTION_UP}
     * @return
     */
    public abstract void onMove(int suggestEventAction);

    /**
     * 无法进行移动事件
     *
     * @param suggetEventAction 建议处理的事件,值可能为{@link MotionEvent#ACTION_MOVE},{@link MotionEvent#ACTION_UP}
     */
    public abstract void onMoveFail(int suggetEventAction);
}

其中除了确认是否可拖动的回调接口,还包括了移动前的回调接口onMove(),无法移动时(可能由于条件不允许等)的回调接口onMoveFail()


偏移量计算

对于偏移量计算规则,上面已经提过了.这里需要补充的是另外几个要点.
首先,偏移量的计算在整个MOVE事件中是一直都在发生的,因为每隔一段时间ACTION_MOVE事件就会触发一次,每触发一次回调则会计算一次偏移量(但不一定会重绘);

每次偏移量的计算都是以 DOWN 事件按下时的坐标为基础的,这说明了每次计算得到的移动偏移量是相对ACTION_DOWN时坐标的偏移量.

其次,由于ACTION_MOVE事件的触发是不稳定的,即使按住坐标没有改变还是会被触发(猜测是每隔一段时间就会触发,而不是基于坐标的变化,原理没有细究确定).一些移动中可能会产生十几甚至几十次ACTION_MOVE事件,而且某些情况下偏移量会非常小(仅有1-2个像素也有可能),所以做了一些的排除措施.

当偏移量达到一定的数值时(计算偏移量的绝对值,因为偏移量可能是负值),才进行一次界面的重绘,以此减少重绘的次数

最后,在整个ACTION_MOVE事件时,每一次有效的偏移量改变时,才会记录到实际偏移量中,之后界面会被重新绘制.
根据以上的流程,我们需要记录的偏移量变量包括:

//任何时候绘制需要的偏移量
protected float mDrawOffsetY = 0f;
protected float mDrawOffsetX = 0f;
//移动过程中临时保存的移动前的偏移量
protected float mTempDrawOffsetX = 0f;
protected float mTempDrawOffsetY = 0f;

其中mDrawOffset变量是任何时候绘制界面时使用的偏移量(不管在ACTION_MOVE事件中还是ACTION_UP); 而mTempDrawOffset则是在ACTION_MOVE移动时保存的移动前的偏移量,用以计算某次移动事件之后的实际偏移量


实现

/**
 * 根据移动的距离计算是否重新绘制
 *
 * @param moveDistanceX    X轴方向的移动距离(可负值)
 * @param moveDistanceY    Y轴方向的移动距离(可负值)
 * @param invalidateAction 重绘的行为标志
 */
private boolean invalidateInSinglePoint(float moveDistanceX, float moveDistanceY, int invalidateAction) {
    if (mMoveEvent == null) {
        return false;
    }
    //此处做大于5的判断是为了避免在检测单击事件时
    //有可能会有很微小的变动,避免这种情况下依然会造成移动的效果
    if (Math.abs(moveDistanceX) > 5 || Math.abs(moveDistanceY) > 5 || invalidateAction == MotionEvent.ACTION_UP) {
        //新的偏移量
        float newDrawOffsetX = mTempDrawOffsetX + moveDistanceX;
        float newDrawOffsetY = mTempDrawOffsetY + moveDistanceY;

        //当前绘制的最左边边界坐标大于0(即边界已经显示在屏幕上时),且移动方向为向右移动
        if (!mMoveEvent.isCanMovedOnX(moveDistanceX, newDrawOffsetX)) {
            //保持原来的偏移量不变
            newDrawOffsetX = mDrawOffsetX;
        }
        //当前绘制的顶端坐标大于0且移动方向为向下移动
        if (!mMoveEvent.isCanMovedOnY(moveDistanceY, newDrawOffsetY)) {
            //



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android中点击事件的实现方式,android事件
  • Android开发2:事件处理及实现简单的对话框,android开发
  • Android面试题--事件处理,android试题--事件
  • Android防止过快点击造成多次事件
  • Android触摸事件(二)-TouchUtils,触摸辅助工具类
  • Android_事件纷发

相关文章

  • 2017-05-26Android中实现APP文本内容的分享发送与接收方法简述,androidapp
  • 2017-05-26Android 手机卫士17--缓存清理,android17--
  • 2017-05-26Yarn上运行spark-1.6.0
  • 2017-05-26Android中Fragment与Activity之间的交互(两种实现方式),androidfragment
  • 2017-05-26TextView,iostextview
  • 2017-05-26Android特效专辑(十)——点击水波纹效果实现,逻辑清晰实现简单
  • 2017-05-26自动完成文本框(AutoCompleteTextView与MultiAutoCompleteTextView)关联适配器,文本框autocomplete
  • 2017-05-26Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能
  • 2017-05-222.6.4 DrawerLayout(官方侧滑菜单)的简单使用
  • 2017-05-26AS400银行核心系统开发中的技术总结--交易和组件写法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android React-Native系列之(一)零基础搭建React-Native开发环境
    • Android 工程集成React Native 0.44 注意点,androidreact
    • 计算facebook sdk需要的key hashes,facebookhashes
    • Android版本和API Level对应关系,androidlevel
    • 最新Android系统版本与API等级对应关系表,androidapi
    • Android 6.0 运行时权限处理完全解析,android6.0
    • 仿拉手团购App5--登录界面,团购app5--登录界面
    • 安卓应用反编译(二)-APK包反编译浅析
    • 输入法出现时,局部上移的代码,输入法上移
    • Kotlin中的“忍者”函数 —— 理解泛型的能力(KAD 12),kotlinkad

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有