Android拖动和缩放

拖拽和缩放

多点触控的理论学完了之后,这里开始实践。本节主要介绍使用onTouchEvent()方法处理触控事件。

拖动一个对象

如果你使用的是Android 3.0或者之后的系统,那么你可以使用内置的拖拽实践监听器`View.OnDragListener`。

用touch手势把一个对象从屏幕的一边拽到另一边是很常见的一种用法。以下代码展示了如何拖拽一个
屏幕上的图片。但是主要一下内容:

  • 在一个拖动(或者叫做scroll)操作里,app需要知道开始触控点,不管有几根指头放在屏幕上
    只需要记住第一根指头的点。但是,在拖动图片的过程中,用户有放上了好几个手指,然后把第一个触控的
    手指拿开了屏幕。如果你的app只记录单个手指的触控操作,那么就需要把第二个手指的触控点作为默认触控点
    并把图片移动到该位置。
  • 为了防止上面的情况发生,你的app需要区分初始触控点和其他的触控点。要记录初始触控点以外的触控点,就需要用到
    前文所说的ACTION_POINTER_DOWNACTION_POINTER_UP事件。ACTION_POINTER_DOWNACTION_POINTER_UP
    可以在onTouchEvent()回调中取得。
  • ACTION_POINTER_UP发生的时候,下面的示例代码可以获取到index,并确保触控ID指向的触控事件是有效的。如果
    触控点已经无效,则获取一个有效的,并获取其X和Y坐标。这个坐标是在ACTION_MOVE事件中获取,图片将被移动到该位置。

以下代码会记录起始触控点的位置,追踪手指移动的新位置,并把图片移动到该位置。并按照上面描述的方法处理可能的异常情况。

注意以下代码用了getActionMasked()方法。为了保证兼容可以使MotionEventCompat.getActionMasked()来获取触控的MotionEvent

补充说明,为了不让读者态度困惑。所以没有使用Google的示例代码。原来的示例代码并没有突出在Activity中拖动一个View的功能。而是主要在一个View内部如何相应拖动和缩放功能。这和前文所述的主题有一定的不符合,所以笔者做了下面的修改。如有不妥请指出。

override fun onTouchEvent(event: MotionEvent?): Boolean {
    var action = MotionEventCompat.getActionMasked(event)

    when (action) {
        MotionEvent.ACTION_DOWN -> {
            val pointerIndex = MotionEventCompat.getActionIndex(event!!)
            val x = MotionEventCompat.getX(event!!, pointerIndex)
            val y = MotionEventCompat.getY(event!!, pointerIndex)

            mLastTouchX = x
            mLastTouchY = y

            mActivePointerId = MotionEventCompat.getPointerId(event, 0)
        }
        MotionEvent.ACTION_MOVE -> {
            val pointerIndex = MotionEventCompat.findPointerIndex(event!!, mActivePointerId)
            val x = MotionEventCompat.getX(event!!, pointerIndex)
            val y = MotionEventCompat.getY(event!!, pointerIndex)

            val dx = x - mLastTouchX!!
            val dy = y - mLastTouchY!!

            mPosX = mPosX ?: 0.0f + dx
            mPosY = mPosY ?: 0.0f + dy

            //                mImageView?.x = mPosX!!
            //                mImageView?.y = mPosY!!
            mImageView?.x = x
            mImageView?.y = y

            Log.d("##DRAG", "Pointer x- $x | y- $y")
            Log.d("##DRAG", "View x- ${mImageView?.x} y- ${mImageView?.y}")

            mLastTouchX = x
            mLastTouchY = y

        }
        MotionEvent.ACTION_UP -> {
            mActivePointerId = INVALID_POINTER_ID
        }
        MotionEvent.ACTION_CANCEL -> {
            mActivePointerId = INVALID_POINTER_ID
        }
        MotionEvent.ACTION_POINTER_UP -> {
            val pointerIndex = MotionEventCompat.getActionIndex(event!!)
            val pointerId = MotionEventCompat.getPointerId(event!!, pointerIndex)

            if (pointerId == mActivePointerId) {
                val newPointerIndex = if (pointerIndex == 0) 1 else 0
                mLastTouchX = MotionEventCompat.getX(event!!, newPointerIndex)
                mLastTouchY = MotionEventCompat.getY(event!!, newPointerIndex)
                mActivePointerId = MotionEventCompat.getPointerId(event!!, newPointerIndex)
            }
        }
    }

    return true
}

总结以下上述内容:

  1. 触控ID(pointer Id)可以唯一制定一个触控事件
  2. index对应的触控事件可能发生改变。但是,只有通过触控的index可以获得触控的坐标。

所以,使用的时候先在ACTION_DOWN里得到触控index,再用触控index获得触控Id存起来。之后每次在ACTION_MOVE事件中,
用触控Id得到触控index,再用这个index得到触控的坐标。

在ACTION_UP、ACTION_CANCEL事件里把触控Id设置为空(或者无效)。在ACTION_POINTER_UP里把作废的触控Id置换为有效的触控Id。

这个是关于触控的坐标的。在默认的Activity里实现这个拖拽的功能,你会发现这个图片在拖动的一瞬间图片会下移一定的距离。
由于图片的大小设定为50dp,下移的距离和这个距离非常接近。在设定为全屏的时候,下移不会再发生。说明触控点的坐标是基于全屏的,
但是ImageView定位的坐标是基于当前的ViewGroup的。这一点也非常重要,如果你需要保留ActionBar的话,坐标数据需要从全屏转化为当前
ImageView所在的ViewGroup的。

to be continued...

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 330987132 | Go:217696290 | Python:336880185 | 做人要厚道,转载请注明出处!

时间: 2024-10-28 01:09:12

Android拖动和缩放的相关文章

android-求大神帮忙啊!Android用手势缩放图片的时候图片变黑

问题描述 求大神帮忙啊!Android用手势缩放图片的时候图片变黑 源码: public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { // TODO Auto-generated method stub velocityX=velocityX>4000?4000:velocityX; velocityX=velocityX<-4000?-4000:velo

android webview设置缩放后返回到上一界面,如何才能让上一界面不能缩放

问题描述 android webview设置缩放后返回到上一界面,如何才能让上一界面不能缩放 android webview的缩放问题: 从一个网页点击图片链接,查看大图,图片设置可以缩放,但是从图片返回到上一页面(goback())后, 原先的网页也能缩放,如何才能让返回后的网页不能缩放呢? 解决方案 http://www.android100.org/html/201401/18/5362.html 解决方案二: 监听BACK 事件,然后在那里判断下当前的缩放大小,有改变,再设置回来就行了.

gui-在qtextedit中实现用鼠标点击图片一角,拖动来缩放图片,要怎么实现?

问题描述 在qtextedit中实现用鼠标点击图片一角,拖动来缩放图片,要怎么实现? 我的想法是先获得图片的坐标,然后通过重写mousePressEvent,mouseMoveEvent等来实现,但是我现在连坐标都不知道怎么获取,小弟小白一个,搜索了好久没有找到解决方案,求教各位 解决方案 鼠标滚轮实现图片的缩放wpf实现图片拖动和缩放

android 图片操作(缩放移动) 实例代码_Android

view_show.xml 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?><LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="match_par

android 图片操作(缩放移动) 实例代码

view_show.xml 复制代码 代码如下:<?xml version="1.0" encoding="utf-8"?><LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="match_pare

Android图片旋转,缩放,位移,倾斜,对称完整示例(二)——Bitmap.createBitmap()和Matrix

MainActivity如下: package cc.c; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.widget.ImageView; /** * Demo描述: * 利用B

Android图片旋转,缩放,位移,倾斜,对称完整示例(一)——imageView.setImageMatrix(matrix)和Matrix

MainActivity如下: import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; import android.app.Activity; import android.graphics.Matrix; /** * Demo描述:

android图片的缩放

  import android.app.Activity;    import android.graphics.Bitmap;    import android.graphics.BitmapFactory;    import android.graphics.Matrix;    import android.graphics.drawable.BitmapDrawable;    import android.os.Bundle;    import android.view.Vie

jquery ui 实现弹层,无遮罩,可拖动,可缩放

弹层 无遮罩 可拖动,可缩放,代码统一,可扩展 输入框: