为了账号安全,请及时绑定邮箱和手机立即绑定

Android图像视图缩放和翻译问题

Android图像视图缩放和翻译问题

心有法竹 2019-06-11 13:56:24
Android图像视图缩放和翻译问题我正在开发一个Android应用程序(API 194.4),我遇到了ImageViews的一些问题。我有一个SurfaceView,在其中我动态地添加了ImageViews,我想对触摸事件做出反应。到目前为止,我已经成功地使ImageView移动和缩放顺利,但我有一个恼人的行为。当我缩小图像到一定的限制(我可以说是原始大小的一半),我试图移动它,图像闪烁。经过一个简短的分析,它似乎是对称地在屏幕上的手指周围切换它的位置,累积距离,最后离开视线(这一切发生得非常快(<1s)。我想我错过了一些东西,与ImageView/SurfaceView相比,触摸事件的相对价值,但我是个菜鸟,而且我被塞进了…这是我的密码public class MyImageView extends ImageView {private ScaleGestureDetector mScaleDetector ; private static final int MAX_SIZE = 1024;private static final String TAG = "MyImageView"; PointF DownPT = new PointF(); // Record Mouse Position When Pressed DownPointF StartPT = new PointF();  // Record Start Position of 'img'public MyImageView(Context context) {     super(context);     mScaleDetector = new ScaleGestureDetector(context,new MySimpleOnScaleGestureListener());     setBackgroundColor(Color.RED);     setScaleType(ScaleType.MATRIX);     setAdjustViewBounds(true);     RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,      RelativeLayout.LayoutParams.WRAP_CONTENT);     lp.setMargins(-MAX_SIZE, -MAX_SIZE, -MAX_SIZE, -MAX_SIZE);     this.setLayoutParams(lp);     this.setX(MAX_SIZE);     this.setY(MAX_SIZE);}int firstPointerID;boolean inScaling=false;@Overridepublic boolean onTouchEvent(MotionEvent event) {     // get pointer index from the event object     int pointerIndex = event.getActionIndex();     // get pointer ID     int pointerId = event.getPointerId(pointerIndex);     //First send event to scale detector to find out, if it's a scale     boolean res = mScaleDetector.onTouchEvent(event);}我还有另外一个关于轮调的问题。我应该如何实现这一点?我是否可以某种方式使用ScalegestureDetector,或者让我让它在视图触摸事件中工作呢?我希望能够以相同的姿态缩放和旋转(并在另一个手势中移动)。谢谢你的帮助,我真的很感激!
查看完整描述

3 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

我试着用矩阵实现多点触摸视图而不是位图,现在我成功了。现在,我认为这将有助于您为多个形象的个人手势。试试看,它对我最有效。

public class MultiTouchImageView extends ImageView implements OnTouchListener{float[] lastEvent = null;float d = 0f;float newRot = 0f;
public static String fileNAME;public static int framePos = 0;//private ImageView view;private boolean isZoomAndRotate;
private boolean isOutSide;// We can be in one of these 3 statesprivate static final int NONE = 0;
private static final int DRAG = 1;private static final int ZOOM = 2;private int mode = NONE;
private PointF start = new PointF();private PointF mid = new PointF();float oldDist = 1f;public MultiTouchImageView(Context context) {
    super(context);}public MultiTouchImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);}public MultiTouchImageView(Context context, AttributeSet attrs) {
    super(context, attrs);}@SuppressWarnings("deprecation")@Overridepublic boolean onTouch(View v, MotionEvent event) {
    //view = (ImageView) v;
    bringToFront();
    // Handle touch events here...
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        //savedMatrix.set(matrix);
        start.set(event.getX(), event.getY());
        mode = DRAG;
        lastEvent = null;
        break;
    case MotionEvent.ACTION_POINTER_DOWN:
        oldDist = spacing(event);
        if (oldDist > 10f) {
            midPoint(mid, event);
            mode = ZOOM;
        }

        lastEvent = new float[4];
        lastEvent[0] = event.getX(0);
        lastEvent[1] = event.getX(1);
        lastEvent[2] = event.getY(0);
        lastEvent[3] = event.getY(1);
        d =  rotation(event);
        break;
    case MotionEvent.ACTION_UP:
        isZoomAndRotate = false;
    case MotionEvent.ACTION_OUTSIDE:
        isOutSide = true;
        mode = NONE;
        lastEvent = null;
    case MotionEvent.ACTION_POINTER_UP:
        mode = NONE;
        lastEvent = null;
        break;
    case MotionEvent.ACTION_MOVE:
        if(!isOutSide){
            if (mode == DRAG && !isZoomAndRotate) {
                isZoomAndRotate = false;
                setTranslationX((event.getX() - start.x) + getTranslationX());
                setTranslationY((event.getY() - start.y) + getTranslationY());
            } else if (mode == ZOOM && event.getPointerCount() == 2) {
                isZoomAndRotate = true;
                boolean isZoom = false;
                if(!isRotate(event)){
                    float newDist = spacing(event);
                    if (newDist > 10f) {
                        float scale = newDist / oldDist * getScaleX();
                        setScaleX(scale);
                        setScaleY(scale);
                        isZoom = true;
                    }
                }
                else if(!isZoom){
                    newRot = rotation(event);
                    setRotation((float)(getRotation() + (newRot - d)));
                }
            }
        }

        break;
    }
    new GestureDetector(new MyGestureDectore());
    Constants.currentSticker = this;
    return true;}private class MyGestureDectore extends GestureDetector.SimpleOnGestureListener{

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        bringToFront();
        return false;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        return false;
    }}private float rotation(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);}private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return FloatMath.sqrt(x * x + y * y);}private void midPoint(PointF point, MotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);}private boolean isRotate(MotionEvent event){
    int dx1 = (int) (event.getX(0) - lastEvent[0]);
    int dy1 = (int) (event.getY(0) - lastEvent[2]);
    int dx2 = (int) (event.getX(1) - lastEvent[1]);
    int dy2 = (int) (event.getY(1) - lastEvent[3]);
    Log.d("dx1 ", ""+ dx1);
    Log.d("dx2 ", "" + dx2);
    Log.d("dy1 ", "" + dy1);
    Log.d("dy2 ", "" + dy2);
    //pointer 1
    if(Math.abs(dx1) > Math.abs(dy1) && Math.abs(dx2) > Math.abs(dy2)) {
        if(dx1 >= 2.0 && dx2 <=  -2.0){
            Log.d("first pointer ", "right");
            return true;
        }
        else if(dx1 <= -2.0 && dx2 >= 2.0){
            Log.d("first pointer ", "left");
            return true;
        }
    }
    else {
         if(dy1 >= 2.0 && dy2 <=  -2.0){
                Log.d("seccond pointer ", "top");
                return true;
            }
            else if(dy1 <= -2.0 && dy2 >= 2.0){
                Log.d("second pointer ", "bottom");
                return true; 
            }

    }

    return false;}}


查看完整回答
反对 回复 2019-06-11
  • 3 回答
  • 0 关注
  • 549 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信