android双指平移、旋转、缩放控件完美版

package com.example.zhouqiong.richeditotandroid.edit;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;

import com.blankj.utilcode.util.ToastUtils;
import com.example.zhouqiong.richeditotandroid.view.CustomsEditText;
import com.example.zhouqiong.richeditotandroid.xzhucourseware.R;
import com.example.zhouqiong.richeditotandroid.xzhucourseware.model.bean.BubbleInfo;
import com.example.zhouqiong.richeditotandroid.xzhucourseware.util.LogUtil;

/**
 * Created by Robert on 2017/6/20.
 */

public class MoveLayout extends RelativeLayout {

    private boolean isBorder = true;

    private int dragDirection = 0;
    private static final int TOP = 0x15;
    private static final int LEFT = 0x16;
    private static final int BOTTOM = 0x17;
    private static final int RIGHT = 0x18;
    private static final int LEFT_TOP = 0x11;
    private static final int RIGHT_TOP = 0x12;
    private static final int LEFT_BOTTOM = 0x13;
    private static final int RIGHT_BOTTOM = 0x14;
    private static final int CENTER = 0x19;


    private int lastX;
    private int lastY;

    private int screenWidth;
    private int screenHeight;

    private int oriLeft;
    private int oriRight;
    private int oriTop;
    private int oriBottom;


    /**
     * 标示此类的每个实例的id
     */
    private int identity = 0;

    /**
     * 保存此布局所显示的Image的本地路径
     */
    private String imgLocalPath;
    /**
     * 保存此布局所显示的Image的服务器地址
     */
    private String imgUrlPath;

    /**
     * 保存此布局锁展示的图标id
     */
    private int imgLocalId;
    private String imgLogcalBitmap;
    /**
     * 图片类型(图片或图标)
     */
    private int imgType;

    /**
     * 保存气泡内边距 及背景图片本地路径
     */
    private BubbleInfo bubbleInfo;
    private String editBg;

    /**
     * 触控区域设定
     */
    private int touchAreaLength = 60;

    private int minHeight = 120;
    private int minWidth = 180;
    private static final String TAG = "MoveLinearLayout";

    private Paint mBorderPaint;

    private float ratio = DEFAULT_RATIO;
    public final static float DEFAULT_RATIO = 1f;

    private boolean isBubble = false;
    private int oriWidth, oriHeight;
    private CustomsEditText customsEditText;

//    private boolean isTopLimit = false;
//    private boolean isBottomLimit = false;


    public MoveLayout(Context context, float ratio) {
        super(context);
        this.ratio = ratio;
        init(context);
    }

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

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

    }

    private void init(Context context) {
        mBorderPaint = new Paint();
        mBorderPaint.setColor(Color.RED);
        mBorderPaint.setStrokeWidth(5.0f);
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setStyle(Paint.Style.STROKE);

        screenHeight = 500;//getResources().getDisplayMetrics().heightPixels - 40;
        screenWidth = 500;// getResources().getDisplayMetrics().widthPixels;

    }

    public void setViewWidthHeight(int width, int height) {
        screenWidth = width;
        screenHeight = height;
    }

    public void setMinHeight(int height) {
        minHeight = height;
        if (minHeight < touchAreaLength * 2) {
            minHeight = touchAreaLength * 2;
        }
    }

    public void setMinWidth(int width) {
        minWidth = width;
        if (minWidth < touchAreaLength * 3) {
            minWidth = touchAreaLength * 3;
        }
    }

    public String getImgUrlPath() {
        return imgUrlPath;
    }

    public void setImgUrlPath(String imgUrlPath) {
        this.imgUrlPath = imgUrlPath;
    }

    public BubbleInfo getBubbleInfo() {
        return bubbleInfo;
    }

    public void setBubbleInfo(BubbleInfo bubbleInfo) {
        this.bubbleInfo = bubbleInfo;
    }

    public String getEditBg() {
        return editBg;
    }

    public void setEditBg(String editBg) {
        this.editBg = editBg;
    }

    public boolean isBorder() {
        return isBorder;
    }

    public void setBorder(boolean border) {
        isBorder = border;
    }

    private int mDeleteHeight = 0;
    private int mDeleteWidth = 0;
    private boolean isInDeleteArea = false;

    public void setDeleteWidthHeight(int width, int height) {
        mDeleteWidth = screenWidth - width;
        mDeleteHeight = height;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

    private boolean isImage = false;
    // 属性变量
    private float translationX; // 移动X
    private float translationY; // 移动Y
    private float scale = 1; // 伸缩比例
    private float rotation; // 旋转角度

    // 移动过程中临时变量
    private float actionX;
    private float actionY;
    private float spacing;
    private float degree;
    private int moveType; // 0=未选择,1=拖动,2=缩放

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mOnTouchListener.onTouch(this);
                moveType = 1;
                actionX = event.getRawX();
                actionY = event.getRawY();
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                moveType = 2;
                spacing = getSpacing(event);
                degree = getDegree(event);
                break;
            case MotionEvent.ACTION_MOVE:
                if (moveType == 1) {
                    translationX = translationX + event.getRawX() - actionX;
                    translationY = translationY + event.getRawY() - actionY;
                    setTranslationX(translationX);
                    setTranslationY(translationY);
                    actionX = event.getRawX();
                    actionY = event.getRawY();
                } else if (moveType == 2) {
                    scale = scale * getSpacing(event) / spacing;
                    setScaleX(scale);
                    setScaleY(scale);
                    rotation = rotation + getDegree(event) - degree;
                    if (rotation > 360) {
                        rotation = rotation - 360;
                    }
                    if (rotation < -360) {
                        rotation = rotation + 360;
                    }
                    setRotation(rotation);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                moveType = 0;
        }
        return true;
    }

    // 触碰两点间距离
    private float getSpacing(MotionEvent event) {
        //通过三角函数得到两点间的距离
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    // 取旋转角度
    private float getDegree(MotionEvent event) {
        //得到两个手指间的旋转角度
        double delta_x = event.getX(0) - event.getX(1);
        double delta_y = event.getY(0) - event.getY(1);
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }

    public int getImgType() {
        return imgType;
    }

    public void setImgType(int imgType) {
        this.imgType = imgType;
    }

    public int getImgLocalId() {
        return imgLocalId;
    }

    public void setImgLocalId(int imgLocalId) {
        this.imgLocalId = imgLocalId;
    }

    public int getIdentity() {
        return identity;
    }

    public void setIdentity(int identity) {
        this.identity = identity;
    }

    public String getImgLocalPath() {
        return imgLocalPath;
    }

    public void setImgLocalPath(String imgLocalPath) {
        this.imgLocalPath = imgLocalPath;
    }

    private OnTouchListener mOnTouchListener;

    protected interface OnTouchListener {
        void onTouch(View view);
    }

    public void setOnTouchListener(OnTouchListener mOnTouchListener) {
        this.mOnTouchListener = mOnTouchListener;
    }

    public boolean isBubble() {
        return isBubble;
    }

    public void setBubble(boolean bubble) {
        isBubble = bubble;
    }

    public int getOriWidth() {
        return oriWidth;
    }

    public void setOriWidth(int oriWidth) {
        this.oriWidth = oriWidth;
    }

    public int getOriHeight() {
        return oriHeight;
    }

    public void setOriHeight(int oriHeight) {
        this.oriHeight = oriHeight;
    }

    public CustomsEditText getCustomsEditText() {
        return customsEditText;
    }

    public void setCustomsEditText(CustomsEditText customsEditText) {
        this.customsEditText = customsEditText;
    }

    public String getImgLogcalBitmap() {
        return imgLogcalBitmap;
    }

    public void setImgLogcalBitmap(String imgLogcalBitmap) {
        this.imgLogcalBitmap = imgLogcalBitmap;
    }
}

转载自:https://www.jianshu.com/p/df34e47bfa2a

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Android平台上,可以使用一些常用的手势操作来实现图片的平移双指缩放和双击放大缩小。 首先,为了实现平移功能,可以使用触摸事件的ACTION_MOVE来处理手指在屏幕上滑动的操作。通过计算滑动距离,可以改变图片的位置从而实现平移效果。 其次,双指缩放可以使用触摸事件的ACTION_POINTER_DOWN和ACTION_POINTER_UP来追踪并处理触摸屏幕上第二个手指按下和松开的操作。在处理时,可以通过计算两个手指触摸点之间的距离来改变图片的缩放比例,从而实现双指缩放效果。 最后,双击放大缩小可以通过设置一个双击的监听器来实现。在双击监听器的回调方法中,可以根据当前的图片缩放状态来判断是进行放大操作还是缩小操作。并根据需要更改图片的缩放比例,实现双击放大缩小功能。 在实现上述功能时,可以使用Android提供的一些核心类来辅助开发,如View、MotionEvent、GestureDetector等。同时,还可以结合自定义View和动画效果来提升用户体验,使图片的平移缩放和双击动作更加流畅和自然。 总之,通过合理运用触摸事件、手势识别、双击监听器等技术,可以在Android上实现图片的平移双指缩放和双击放大缩小功能,从而提升用户与应用程序的交互体验。 ### 回答2: 在Android开发中,可以通过使用ImageView控件来实现对图片的平移双指缩放和双击放大缩小操作。 1. 平移:可以通过使用Matrix类对ImageView进行变换来实现图片的平移。首先,我们需要为ImageView设置一个OnTouchListener来监听用户的手势操作。在手势操作的回调方法中,可以通过获取手指按下和移动的位置差来计算出需要平移的距离,然后通过设置Matrix的平移矩阵来实现图片的平移效果。 2. 双指缩放:可以通过GestureDetector类来监听双指缩放手势。在手势操作的回调方法中,可以获取到两个手指的起始位置和当前位置,通过计算两个手指之间的距离差来判断缩放的比例。然后,再通过设置Matrix的缩放矩阵来实现图片的缩放效果。需要注意的是,在进行缩放操作时,还需要考虑到手指中心点的位置变化。 3. 双击放大缩小:也可以通过GestureDetector类来监听双击手势。在手势操作的回调方法中,可以判断是否发生了双击事件,并获取到双击的位置。当双击事件发生时,可以通过判断当前图片的缩放比例来决定是放大还是缩小。通过设置Matrix的缩放矩阵和平移矩阵来实现图片的放大缩小效果。 需要注意的是,为了实现图片的平移双指缩放和双击放大缩小操作,我们需要对ImageView进行一系列的监听和处理操作。同时,为了方便管理和控制这些操作,可以将相关的代码封装成一个自定义的图片控件,并在该控件中进行处理。 ### 回答3: Android 提供了多种方法来实现图片的平移双指缩放和双击放大缩小功能。 首先,要实现图片的平移,我们可以使用 GestureDetector 类。可以通过重写 onScroll() 方法来检测用户的滑动手势,然后将图片的位置进行相应的调整,从而实现平移效果。 其次,要实现双指缩放功能,我们可以借助 ScaleGestureDetector 类。通过重写 onScale() 方法,我们可以获取用户的缩放手势,并根据手势的缩放比例调整图片的尺寸,从而实现双指缩放的效果。 最后,要实现双击放大缩小功能,我们可以使用 GestureDetector 类。可以通过重写 onDoubleTap() 方法来检测用户的双击手势,然后根据当前图片的尺寸和双击事件的位置,来判断是进行放大还是缩小操作,最后将图片的尺寸进行相应的调整,实现双击放大缩小的效果。 需要注意的是,以上的功能实现是基于 Android 的原生 API,还有其他第三方库也提供了更便捷的方法来实现这些功能,例如 PhotoView 库,它提供了更多灵活的选项和交互效果,可以更加方便地实现图片的平移缩放和双击操作。 综上所述,Android 针对图片的平移双指缩放和双击放大缩小,可以通过重写相应的手势监听方法或使用第三方库来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值