Android ImageView 缩放、拖动、旋转

直接上代码


    <cn.weijian.sweeping_robot.widget.MatrixImageView
        android:layout_above="@id/robot_bottom_layout"
        android:id="@+id/slamware_map_image_view"
        android:scaleType="matrix"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:src="@drawable/map"/>

package cn.weijian.sweeping_robot.widget;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
//import android.support.v7.widget.AppCompatImageView;
import android.widget.ImageView;
import androidx.annotation.Nullable;

import cn.weijian.sweeping_robot.utils.ViewUtils;

public class MatrixImageView extends ImageView {
    private static final String TAG = MatrixImageView.class.getSimpleName();

    private Matrix currentMatrix = new Matrix();
    private Matrix savedMatrix = new Matrix();

    private PointF startF = new PointF();
    private PointF midF = new PointF();

    private float oldDis = 1f;          // 初始的两个手指按下的触摸点的距离
    private float saveRotate = 0F;      // 保存了的角度值

    private static final int MODE_NONE = 0; // 默认的触摸模式
    private static final int MODE_DRAG = 1; // 拖拽模式
    private static final int MODE_ZOOM = 2; // 缩放模式
    private int mode = MODE_NONE;

    private int ddx=0, ddy=0;
    private float dScale = 1;

    public MatrixImageView(Context context) {
        super(context);
        init();
    }

    public MatrixImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MatrixImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public MatrixImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init(){
        Log.e(TAG, "width: "+getWidth()+", height: "+getHeight());
        setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return true;
            }
        });
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                ImageView view = (ImageView)v;
                switch (event.getAction()& MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN:// 单点接触屏幕时
                        savedMatrix.set(currentMatrix);
                        startF.set(event.getX(), event.getY());
                        mode=MODE_DRAG;
                        break;

                    case MotionEvent.ACTION_POINTER_DOWN:// 第二个手指按下事件
                        oldDis = ViewUtils.calDis(event);
                        if (oldDis > 10F) {
                            savedMatrix.set(currentMatrix);
                            midF = ViewUtils.calMidPoint(event);
                            mode = MODE_ZOOM;
                        }
                        saveRotate = ViewUtils.calRotation(event);//计算初始的角度
                        break;
                    case MotionEvent.ACTION_MOVE:// 触摸点移动时
                        if (mode == MODE_DRAG) {
                            // 单点触控拖拽平移
                            float dx = event.getX() - startF.x;
                            float dy = event.getY() - startF.y;
                            startF.set(event.getX(), event.getY());
//                            if(Math.abs(ddx+dx)<=view.getWidth()*dScale && Math.abs(ddy+dy)<=view.getHeight()*dScale)
                            {
                                ddx+=dx;
                                ddy+=dy;
                                currentMatrix.postTranslate(dx, dy);
                            }
                        }
                        else if(mode == MODE_ZOOM && event.getPointerCount() == 2){
                            // 两点触控拖放
                            float newDis = ViewUtils.calDis(event);
                            float rotate = ViewUtils.calRotation(event);

                            //指尖移动距离大于10F缩放
                            if (newDis > 10F){
                                float scale = newDis / oldDis;
                                oldDis = newDis;
                                if(scale*dScale<10 && scale*dScale>0.1){
                                    dScale *= scale;
                                    currentMatrix.postScale(scale, scale, midF.x, midF.y);
                                    Log.e(TAG, "dScale: "+dScale+", scale: "+scale);
                                }
                            }

                            //当旋转的角度大于5F才进行旋转
                            if(Math.abs(rotate - saveRotate)>1F){
                                currentMatrix.postRotate(rotate - saveRotate, view.getWidth() / 2, view.getHeight() / 2);
                                saveRotate = rotate;
                                Log.e(TAG, "saveRotate: "+saveRotate+", rotate: "+rotate);
                            }
                        }
                        break;

                    case MotionEvent.ACTION_UP:// 单点离开屏幕时
                        mode=MODE_NONE;
                        break;
                    case MotionEvent.ACTION_POINTER_UP:// 第二个点离开屏幕时
                        savedMatrix.set(currentMatrix);
                        if(event.getActionIndex()==0)
                            startF.set(event.getX(1), event.getY(1));
                        else if(event.getActionIndex()==1)
                            startF.set(event.getX(0), event.getY(0));
                        mode=MODE_DRAG;
                        break;
                }
                view.setImageMatrix(currentMatrix);
                return false;
            }
        });
    }

    public Matrix getCurrentMatrix() {
        return currentMatrix;
    }

    public Matrix getSavedMatrix() {
        return savedMatrix;
    }

    public float getSaveRotate() {
        return saveRotate;
    }
}

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android开发中,我们可以使用触摸事件处理来实现图片的拖拽、缩放旋转操作。 首先,要实现拖拽功能,我们需要监听触摸事件,并在触摸事件的ACTION_MOVE中更新图片的位置。我们可以通过获取触摸点的坐标,然后根据图片的尺寸和移动的距离来计算新的位置,并将图片设置到新的位置上。 其次,要实现缩放功能,我们同样需要监听触摸事件。在触摸事件的ACTION_POINTER_DOWN和ACTION_MOVE中,我们可以获取到两个触摸点的坐标,并根据它们之间的距离来计算缩放比例。然后我们可以通过Matrix矩阵来设置图片的缩放比例,并将新的Matrix应用到图片上。 最后,实现旋转功能也需要监听触摸事件。在触摸事件的ACTION_POINTER_DOWN和ACTION_MOVE中,我们可以获取到两个触摸点的坐标,并根据它们之间的角度差来计算旋转的角度。同样,我们可以通过Matrix矩阵来设置图片的旋转角度,并将新的Matrix应用到图片上。 需要注意的是,为了能够拖拽、缩放旋转图片,我们需要在布局文件中将图片包裹在一个可交互的控件中,如FrameLayout或ImageView。并且在Java代码中,我们需要实现View的触摸事件监听接口,并重写相应的方法来处理触摸事件。 - 以上所述是一种基本的实现方式,在实际开发中,还可以结合手势检测器(GestureDetector)等技术来简化操作和增加灵活性。同时,还要注意处理边界问题和多点触控的情况,以提供更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小康师兄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值