2016-06-07 74 views
3

我有天努力使这项工作,检查了一些其他的答案,没有人可以为我工作:S移动,缩放和旋转ImageView的OnTouch不工作

我的标签添加到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); 

应用程序编译并没有崩溃,但贴纸的确,我已经尝试NOTHING 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; 
      } 
     }); 
    } 
} 
+0

首先,你不明白手势的工作。下面的答案与上面的代码是正确的,因为使用触摸,它不同于点击。详细了解Google Doc中的所有手势。 – GensaGames

+0

这是没有错的,我只是在用户使用ClickListener选择它时触发特定项目的手势,当TouchListener处于活动状态时,没有调用Click Listener,当用户单击项目外部时,图像被取消选择,并且您无法使用手势 –

+0

另一个重要的事情是,我创建了另一个项目,使用手势代码(没有我的应用程序的所有复杂性),它也不能工作... –

回答

1

试试这个..the上述代码不起作用的原因是因为TouchListener和Cli ckListener不能在上面situation..Click共同努力,需要你触摸,然后离开了该事件occur.However触摸事件的视图要求你还在触摸查看...

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

你可以听DOWN和UP Touch Events以处理你想要的拖动效果。 –

+0

我这样做的原因是,我实际上激活了触摸功能,当我点击图像,就好像我先选择图像,然后我开始操纵它,当我离开选择,然后返回到正常的点击功能。 –

+0

你可以发布取消选择代码.. –

2

有趣对于onTouch事件您实例化新的ScaleGestureDetector,RotateGestureDetectorMoveGestureDetector

考虑每个各自的姿态探测器需要之前的触摸事件,以确定并解释如何应对这种说法无疑是您的问题的显著部分,因为你创建的每个触摸事件的新姿态探测器。事实上,如果你在源的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. 

对于初学者来说,你应该确保你只创建一个检测对象,因此它可以消耗所有触摸事件。

+0

我已经找到了解决方案,这是其中之一问题,但我缺乏一个很好的解释,谢谢!另一个问题是图像被设置为WRAP_CONTENT,并且此代码不会移动/缩放/旋转ImageView中的ImageView,而是ImageView中的Drawable,因此ImageView必须是MATCH_PARENT,这会导致更大的问题。我只能编辑LAST添加的图像...(它需要ImageView作为矩阵如此缩放并旋转到该矩阵中,我希望该矩阵是我的FrameLayout,但我不知道如何更改此) –

+0

好吧,赏金时期已经结束,到目前为止,你是唯一一个点击了其中一个点,所以我会奖励你,但是,我的问题并不完全(或完全)解决。 –