移动,缩放和旋转ImageView OnTouch无法正常工作

时间:2016-06-07 02:52:01

标签: android rotation multi-touch

我有几天尝试做这项工作,检查了一些其他答案,似乎没有一个对我有用:S

我为RelativeLayout添加了一个贴纸,我希望贴纸一旦被选中就可以使用OnTouch方法移动,缩放和旋转(它有一个调用setOnTouchListener的OnClickListener) 请记住,我可以添加N贴纸。

private void addSticker(ImageView sticker)
{

    flMemeFrame.addView(sticker);

    sticker.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            {
                if (selectedView != null)
                {
                    CancelSelection(selectedView);
                }
                selectedView = v;

                v.setOnTouchListener(new View.OnTouchListener()
                {
                    private float mScaleFactor = 0.5f;
                    private float mRotationDegree = 0.f;
                    private float mFocusX = 0.f;
                    private float mFocusY = 0.f;
                    private int mScreenHeight;
                    private int mScreenWidth;
                    private Matrix matrix = new Matrix();//Các lớp Matrix giữ một ma trận 3x3 để di chuyển tọa độ.
                    private int mImageWidth, mImageHeight;
                    private ScaleGestureDetector mScaleDetector;
                    private RotateGestureDetector mRotateDetector;
                    private MoveGestureDetector mMoveDetector;

                    class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
                        @Override
                        public boolean onScale(ScaleGestureDetector detector) {
                            mScaleFactor *= detector.getScaleFactor();
                            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 1.0f));
                            return true;
                        }
                    }

                    class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
                        @Override
                        public boolean onRotate(RotateGestureDetector detector) {
                            mRotationDegree -= detector.getRotationDegreesDelta();
                            return true;
                        }
                    }

                    class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener {
                        @Override
                        public boolean onMove(MoveGestureDetector detector) {
                            PointF d = detector.getFocusDelta();
                            mFocusX += d.x;
                            mFocusY += d.y;

                            return true;
                        }
                    }
                    @Override
                    public boolean onTouch(View v, MotionEvent event)
                    {
                        mImageHeight = v.getHeight();
                        mImageWidth = v.getWidth();

                        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
                        mRotateDetector = new RotateGestureDetector(context, new RotateListener());
                        mMoveDetector = new MoveGestureDetector(context, new MoveListener());

                        mScaleDetector.onTouchEvent(event);
                        mRotateDetector.onTouchEvent(event);
                        mMoveDetector.onTouchEvent(event);
                        float scaleImageCenterX = (mImageWidth * mScaleFactor) / 2;
                        float scaleImageCenterY = (mImageHeight * mScaleFactor) / 2;

                        matrix.reset();
                        matrix.postScale(mScaleFactor, mScaleFactor);
                        matrix.postRotate(mRotationDegree, scaleImageCenterX, scaleImageCenterY);
                        matrix.postTranslate(mFocusX - scaleImageCenterX, mFocusY - scaleImageCenterY);

                        ImageView view = (ImageView) v;
                        view.setScaleType(ImageView.ScaleType.MATRIX);
                        view.setImageMatrix(matrix);

                        return true;
                    }
                });
            }
        }
    });
}

这里是我设置图像的地方

ImageView sticker = new ImageView(context);
                RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT);
                rlp.addRule(RelativeLayout.CENTER_IN_PARENT);
                sticker.setLayoutParams(rlp);
addSticker(sticker);

该应用程序编译并且没有崩溃,但贴纸没有OnTouch :(

我尝试过的链接:

http://code.almeros.com/android-multitouch-gesture-detectors#.V1Y0sZMrLMW

rotation and scaling and move using multi touch in android

和其他一些我现在找不到的链接

任何有帮助的人?

编辑:CancelSelection的代码(完全不相关,因为我唯一要做的就是将selectedView设置为null并删除背景,我也删除了OnTouchListener,因为我不想移动/缩放/旋转查看是否未选中)

@SuppressWarnings("deprecation")
public void CancelSelection(View v)
{
    if(isCaptionEditPanelOpen)
    {
        rlQuickEdit.setVisibility(View.GONE);
        rlQuickEdit = null;
        isCaptionEditPanelOpen = false;
    }
    //toogleButtonVisibility(false);
    v.setBackgroundColor(getResources().getColor(android.R.color.transparent));
    selectedView = null;
    v.setOnTouchListener(null);
}

我写了这个课程,看看我是否可以在没有应用程序复杂性的情况下使其工作,结果相同:

package com.andujardev.imagerotation;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity
{
    Context context;
    ImageView imgRotate;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        imgRotate = (ImageView) findViewById(R.id.imgRotate);

        imgRotate.setOnTouchListener(new View.OnTouchListener()
        {
            private float mScaleFactor = 0.5f;
            private float mRotationDegree = 0.f;
            private float mFocusX = 0.f;
            private float mFocusY = 0.f;
            private int mScreenHeight;
            private int mScreenWidth;
            private Matrix matrix = new Matrix();
            private int mImageWidth, mImageHeight;
            private ScaleGestureDetector mScaleDetector;
            private RotateGestureDetector mRotateDetector;
            private MoveGestureDetector mMoveDetector;

            class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
                @Override
                public boolean onScale(ScaleGestureDetector detector) {
                    mScaleFactor *= detector.getScaleFactor();
                    mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 1.0f));
                    return true;
                }
            }

            class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
                @Override
                public boolean onRotate(RotateGestureDetector detector) {
                    mRotationDegree -= detector.getRotationDegreesDelta();
                    return true;
                }
            }

            class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener {
                @Override
                public boolean onMove(MoveGestureDetector detector) {
                    PointF d = detector.getFocusDelta();
                    mFocusX += d.x;
                    mFocusY += d.y;

                    return true;
                }
            }
            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                mImageHeight = v.getHeight();
                mImageWidth = v.getWidth();

                mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
                mRotateDetector = new RotateGestureDetector(context, new RotateListener());
                mMoveDetector = new MoveGestureDetector(context, new MoveListener());

                mScaleDetector.onTouchEvent(event);
                mRotateDetector.onTouchEvent(event);
                mMoveDetector.onTouchEvent(event);
                float scaleImageCenterX = (mImageWidth * mScaleFactor) / 2;
                float scaleImageCenterY = (mImageHeight * mScaleFactor) / 2;

                matrix.reset();
                matrix.postScale(mScaleFactor, mScaleFactor);
                matrix.postRotate(mRotationDegree, scaleImageCenterX, scaleImageCenterY);
                matrix.postTranslate(mFocusX - scaleImageCenterX, mFocusY - scaleImageCenterY);

                ImageView view = (ImageView) v;
                view.setImageMatrix(matrix);

                return true;
            }
        });
    }
}

2 个答案:

答案 0 :(得分:2)

有趣的是,对于每个 onTouch事件,您实例化一个新的ScaleGestureDetectorRotateGestureDetectorMoveGestureDetector

考虑每个相应的手势检测器需要先前的触摸事件来确定和解释如何做出反应这是您的问题的重要部分,因为您为每个触摸事件创建了新的手势检测器。实际上,如果您查看Almeros方法的onTouchEvent(MotionEvent ev)检测器的来源,请说明:

Applications should pass a complete and consistent event stream to this method.
* A complete and consistent event stream involves all MotionEvents from the initial
* ACTION_DOWN to the final ACTION_UP or ACTION_CANCEL.

对于初学者,您应该确保只创建单个检测器对象,以便它可以消耗所有触摸事件。

答案 1 :(得分:1)

试试这个..上述代码无效的原因是因为TouchListener和ClickListener在上述情况下不能一起工作。点击要求你触摸然后离开事件视图。但是Touch事件需要你还在触摸视图......

private void addSticker(ImageView sticker)
{

flMemeFrame.addView(sticker);

sticker.setOnTouchListener(new View.OnTouchListener()
            {
                private float mScaleFactor = 0.5f;
                private float mRotationDegree = 0.f;
                private float mFocusX = 0.f;
                private float mFocusY = 0.f;
                private int mScreenHeight;
                private int mScreenWidth;
                private Matrix matrix = new Matrix();//Các lớp Matrix giữ một ma trận 3x3 để di chuyển tọa độ.
                private int mImageWidth, mImageHeight;
                private ScaleGestureDetector mScaleDetector;
                private RotateGestureDetector mRotateDetector;
                private MoveGestureDetector mMoveDetector;

                class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
                    @Override
                    public boolean onScale(ScaleGestureDetector detector) {
                        mScaleFactor *= detector.getScaleFactor();
                        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 1.0f));
                        return true;
                    }
                }

                class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
                    @Override
                    public boolean onRotate(RotateGestureDetector detector) {
                        mRotationDegree -= detector.getRotationDegreesDelta();
                        return true;
                    }
                }

                class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener {
                    @Override
                    public boolean onMove(MoveGestureDetector detector) {
                        PointF d = detector.getFocusDelta();
                        mFocusX += d.x;
                        mFocusY += d.y;

                        return true;
                    }
                }
                @Override
                public boolean onTouch(View v, MotionEvent event)
                {
                    mImageHeight = v.getHeight();
                    mImageWidth = v.getWidth();

                    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
                    mRotateDetector = new RotateGestureDetector(context, new RotateListener());
                    mMoveDetector = new MoveGestureDetector(context, new MoveListener());

                    mScaleDetector.onTouchEvent(event);
                    mRotateDetector.onTouchEvent(event);
                    mMoveDetector.onTouchEvent(event);
                    float scaleImageCenterX = (mImageWidth * mScaleFactor) / 2;
                    float scaleImageCenterY = (mImageHeight * mScaleFactor) / 2;

                    matrix.reset();
                    matrix.postScale(mScaleFactor, mScaleFactor);
                    matrix.postRotate(mRotationDegree, scaleImageCenterX, scaleImageCenterY);
                    matrix.postTranslate(mFocusX - scaleImageCenterX, mFocusY - scaleImageCenterY);

                    ImageView view = (ImageView) v;
                    view.setScaleType(ImageView.ScaleType.MATRIX);
                    view.setImageMatrix(matrix);

                    return true;
                }
            });
        }
    }