2016-06-07 82 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

好吧,賞金時期已經結束,到目前爲止,你是唯一一個點擊了其中一個點,所以我會獎勵你,但是,我的問題並不完全(或完全)解決。 –