移动、缩放和旋转ImageView OnTouch不工作



我花了几天时间试图让它发挥作用,检查了一些其他答案,但似乎没有一个对我有效: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);

该应用程序可以编译,没有崩溃,但贴纸在触摸时什么都不做:(

我尝试过的链接:

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

在安卓中使用多点触摸进行旋转、缩放和移动

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

有谁能帮忙吗?

编辑:取消选择的代码(完全无关,因为我唯一要做的就是将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;
}
});
}
}

有趣的是,对于每个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.

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

试试这个。。上述代码不起作用的原因是TouchListener和ClickListener在上述情况下无法协同工作。。单击要求您触摸然后离开视图,以便事件发生。然而,触摸事件要求您仍在触摸视图。。。

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;
}
});
}
}