2012-05-23 2 views
0

Я новичок в ANDROID и хочу повернуть, масштабировать и перемещать изображение в своем собственном представлении. Но я пишу все (вращать, масштабировать, перемещать) в том же методе onTouchEvent. Поэтому, когда я перемещаю изображение, оно также поворачивается или меняет изображение, оно перемещается. Я должен обрабатывать их отдельно, но не знаю, как это сделать. Я думаю, что могу добавить кнопку, например, имя которой «вращается». Поэтому я могу исправить изображение, и он просто позволяет вращаться. Но я не могу создать кнопку в своем пользовательском представлении. Код показан ниже:Как я могу вращать, масштабировать и перемещать изображение в Android

 
public class MyView extends View {

// The ‘active pointer’ is the one currently moving our object. private int mActivePointerId = INVALID_POINTER_ID; private static final int INVALID_POINTER_ID = -1; private ScaleGestureDetector mScaleDetector; private float mScaleFactor = 1.f; private float mPosX; private float mPosY; private float mLastTouchX; private float mLastTouchY; //For Fetching image private Bitmap bmp; private Drawable image; private byte[] byteArray; private ByteArrayBuffer baf = null; //For Rotation int direction = 0; int degree = 0; private float centerX ; private float centerY ; private float newX ; private float newY ; private float rotateX; private float rotateY; public MyView(Context context) { this(context, null, 0); } public MyView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); String url = "http://www.queness.com/resources/images/png/apple_ex.png"; AsyncTask<String,Void,ByteArrayBuffer> connection=new GetUrlData().execute(url); try { baf=connection.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } byteArray = baf.toByteArray(); bmp = BitmapFactory.decodeByteArray(byteArray, 0 , byteArray.length); image =new BitmapDrawable(context.getResources() , bmp); image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight()); mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLACK); //For Rotation int height = this.getHeight(); int width = this.getWidth(); centerX = width/2; centerY = height/2; canvas.rotate(direction, width/2, height/2); canvas.save(); canvas.translate(mPosX, mPosY); canvas.scale(mScaleFactor, mScaleFactor); image.draw(canvas); canvas.restore(); } //For Rotation private void updateRotation(float newX2, float newY2) { degree = (int)Math.toDegrees(Math.atan2(newY, newX))-90; setDirection(degree); } //For Rotation public void setDirection(int direction) { this.direction = direction; this.invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { // Let the ScaleGestureDetector inspect all events. mScaleDetector.onTouchEvent(event); final int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { final float x = event.getX(); final float y = event.getY(); mLastTouchX = x; mLastTouchY = y; mActivePointerId = event.getPointerId(0); } if (action == MotionEvent.ACTION_MOVE) { final int pointerIndex = event.findPointerIndex(mActivePointerId); final float x = event.getX(pointerIndex); final float y = event.getY(pointerIndex); // Only move if the ScaleGestureDetector isn't processing a gesture. if (!mScaleDetector.isInProgress()) { final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mPosX += dx; mPosY += dy; invalidate(); } mLastTouchX = x; mLastTouchY = y; //For Rotation rotateX = event.getX(); rotateY = event.getY(); newX = centerX-rotateX; newY = centerY-rotateY; updateRotation(newX, newY); } if (action == MotionEvent.ACTION_UP) { mActivePointerId = INVALID_POINTER_ID; updateRotation(newX, newY); } if (action == MotionEvent.ACTION_CANCEL) { mActivePointerId = INVALID_POINTER_ID; } if (action == MotionEvent.ACTION_POINTER_UP) { final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = event.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { // This was our active pointer going up. Choose a new // active pointer and adjust accordingly. final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = event.getX(newPointerIndex); mLastTouchY = event.getY(newPointerIndex); mActivePointerId = event.getPointerId(newPointerIndex); } } return true; } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); // Don't let the object get too small or too large. mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); invalidate(); return true; } }

}

Я надеюсь, что я могу сказать, что я хочу. Не могли бы вы мне помочь в этом вопросе, пожалуйста?

+2

понимают все понятия и писать все коды вместе и я предлагаю вам понять и не делают копию пасты –

+0

посмотреть на это http://developer.android.com/resources/samples/ApiDemos/src/ com/example/android/apis/animation/index.html –

+0

@ThiruVT Вы совершенно правы в своем комментарии. Я скопировал - вставил свой код и понял, что ничего не знаю о своем вопросе. Но после этого я искал и понимал, о чем все, и сам справлялся со своей проблемой. Поэтому благодарим ваш совет. – angaraeski

ответ

2

Попробуйте использовать ниже код, который работает для меня.

float[] lastEvent = null; 
float d = 0f; 
float newRot = 0f; 
private Matrix matrix = new Matrix(); 
private Matrix savedMatrix = new Matrix(); 
public static String fileNAME; 
public static int framePos = 0; 

private float scale = 0; 
private float newDist = 0; 

// Fields 
private String TAG = this.getClass().getSimpleName(); 

// We can be in one of these 3 states 
private static final int NONE = 0; 
private static final int DRAG = 1; 
private static final int ZOOM = 2; 
private int mode = NONE; 

// Remember some things for zooming 
private PointF start = new PointF(); 
private PointF mid = new PointF(); 
float oldDist = 1f; 

public boolean onTouch(View v, MotionEvent event) { 
      ImageView view = (ImageView) v; 

      // 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) { 
        savedMatrix.set(matrix); 
        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: 
      case MotionEvent.ACTION_POINTER_UP: 
       mode = NONE; 
       lastEvent = null; 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if (mode == DRAG) { 
        // ... 
        matrix.set(savedMatrix); 
        matrix.postTranslate(event.getX() - start.x, event.getY() 
          - start.y); 
       } else if (mode == ZOOM && event.getPointerCount() == 2) { 
        float newDist = spacing(event); 
        matrix.set(savedMatrix); 
        if (newDist > 10f) { 
         float scale = newDist/oldDist; 
         matrix.postScale(scale, scale, mid.x, mid.y); 
        } 
        if (lastEvent != null) { 
         newRot = rotation(event); 
         float r = newRot - d; 
         matrix.postRotate(r, view.getMeasuredWidth()/2, 
           view.getMeasuredHeight()/2); 
        } 
       } 
       break; 
      } 

      view.setImageMatrix(matrix); 

      return true; 
     } 

// Для поворота изображения на мультитач.

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); 
    } 
Смежные вопросы