2010-02-03 192 views
3

我有一個帶有圖像的佈局(嵌入在ImageView中)。我需要旋轉圖像(比方說)逆時針90度。在佈局中旋轉ImageView ...如何?

我寫代碼的動畫圖像旋轉...:

public class MainActivity extends Activity 
{ 
    private ImageView mImageView = null; 
    private Animation mRotateAnimation = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     mImageView = (ImageView) findViewById(R.id.my_image); 
     mRotateAnimation = AnimationUtils.loadAnimation(this, R.anim.my_rotate_90); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      mImageView.startAnimation(mRotateAnimation); 
      return true; 
     } 
     return super.onTouchEvent(event); 
    } 
} 

圖像平滑旋轉90度,但隨後彈回原來的狀態。這是Android文檔所說的將在動畫完成後發生的事情。據推測,在動畫已結束的通知中,我應該轉換ImageView(或底層繪圖),並可能使其無效以觸發重繪。

一切順利,除了那我找不到一個方法來做到這一點,我找不到任何其他人的例子

我試過getImageMatix/setImageMatrixmImageView,沒有明顯的效果。有Drawable的子類可以旋轉圖像,但ImageView上沒有setDrawable()方法,所以我不知道如何使用它。

我搜索了這些例子;雖然其中一些涉及動畫和旋轉(尤其是LunarLander),但它們都不會動畫ImageView,然後將其保留在某種轉換狀態。

當然,我在這裏錯過了一些簡單的... aaaargh,你如何旋轉佈局內的ImageView?

謝謝。

+0

我應該補充一點,90度只是一個不錯的圓形例子。旋轉可以是任何度數,因此「使每個圖像的四個版本:0,90,180和270度旋轉」不會成爲解決方案。 – 2010-02-06 00:46:20

回答

2

ImageView setImageDrawable將在圖像中配置drawable。這應該允許您使用ImageView類,從而使用該功能。

0

試試這個MultiTouchImageView,它對我來說工作得很好。

public class MultiTouchImageView extends ImageView implements OnTouchListener{ 

float[] lastEvent = null; 
float d = 0f; 
float newRot = 0f; 
public static String fileNAME; 
public static int framePos = 0; 
//private ImageView view; 
private boolean isZoomAndRotate; 
private boolean isOutSide; 
// 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; 

private PointF start = new PointF(); 
private PointF mid = new PointF(); 
float oldDist = 1f; 
public MultiTouchImageView(Context context) { 
    super(context); 
} 


public MultiTouchImageView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 


public MultiTouchImageView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 


@SuppressWarnings("deprecation") 
@Override 
public boolean onTouch(View v, MotionEvent event) { 
    //view = (ImageView) v; 
    bringToFront(); 
    // 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) { 
      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: 
     isZoomAndRotate = false; 
    case MotionEvent.ACTION_OUTSIDE: 
     isOutSide = true; 
     mode = NONE; 
     lastEvent = null; 
    case MotionEvent.ACTION_POINTER_UP: 
     mode = NONE; 
     lastEvent = null; 
     break; 
    case MotionEvent.ACTION_MOVE: 
     if(!isOutSide){ 
      if (mode == DRAG && !isZoomAndRotate) { 
       isZoomAndRotate = false; 
       setTranslationX((event.getX() - start.x) + getTranslationX()); 
       setTranslationY((event.getY() - start.y) + getTranslationY()); 
      } else if (mode == ZOOM && event.getPointerCount() == 2) { 
       isZoomAndRotate = true; 
       boolean isZoom = false; 
       if(!isRotate(event)){ 
        float newDist = spacing(event); 
        if (newDist > 10f) { 
         float scale = newDist/oldDist * getScaleX(); 
         setScaleX(scale); 
         setScaleY(scale); 
         isZoom = true; 
        } 
       } 
       else if(!isZoom){ 
        newRot = rotation(event); 
        setRotation((float)(getRotation() + (newRot - d))); 
       } 
      } 
     } 

     break; 
    } 
    new GestureDetector(new MyGestureDectore()); 
    Constants.currentSticker = this; 
    return true; 
} 
private class MyGestureDectore extends GestureDetector.SimpleOnGestureListener{ 

    @Override 
    public boolean onDoubleTap(MotionEvent e) { 
     bringToFront(); 
     return false; 
    } 

    @Override 
    public boolean onDoubleTapEvent(MotionEvent e) { 
     return false; 
    } 

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

private boolean isRotate(MotionEvent event){ 
    int dx1 = (int) (event.getX(0) - lastEvent[0]); 
    int dy1 = (int) (event.getY(0) - lastEvent[2]); 
    int dx2 = (int) (event.getX(1) - lastEvent[1]); 
    int dy2 = (int) (event.getY(1) - lastEvent[3]); 
    Log.d("dx1 ", ""+ dx1); 
    Log.d("dx2 ", "" + dx2); 
    Log.d("dy1 ", "" + dy1); 
    Log.d("dy2 ", "" + dy2); 
    //pointer 1 
    if(Math.abs(dx1) > Math.abs(dy1) && Math.abs(dx2) > Math.abs(dy2)) { 
     if(dx1 >= 2.0 && dx2 <= -2.0){ 
      Log.d("first pointer ", "right"); 
      return true; 
     } 
     else if(dx1 <= -2.0 && dx2 >= 2.0){ 
      Log.d("first pointer ", "left"); 
      return true; 
     } 
    } 
    else { 
     if(dy1 >= 2.0 && dy2 <= -2.0){ 
       Log.d("seccond pointer ", "top"); 
       return true; 
      } 
      else if(dy1 <= -2.0 && dy2 >= 2.0){ 
       Log.d("second pointer ", "bottom"); 
       return true; 
      } 

    } 

    return false; 
} 
}