2010-02-03 5 views
3

이미지가있는 레이아웃이 있습니다 (ImageView에 임베드 됨). 이미지를 90도 CCW로 회전시켜야합니다. 내가 회전 이미지를 애니메이션하는 코드를 작성했습니다레이아웃 내에서 ImageView 회전 ... 어떻게합니까?

... : 이미지가 원활하게 90도 회전하지만, 다시 원래 상태로 고정

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

. 애니메이션이 완료된 후 안드로이드 설명서에서 말하는 것입니다. 아마도 애니메이션이 종료되었다는 알림에서 ImageView (또는 기본 드로어 블)를 변형하고 다시 그릴 수 있도록 무효화 할 수 있습니다.

나는 그것을 할 수있는 방법을 찾을 수 없으며 그걸 수행하는 다른 사람의 예를 찾을 수 없습니다..

/setImageMatrixmImageView에 사용해 보았습니다. 아무런 효과가 없었습니다. 이미지를 회전시킬 Drawable 하위 클래스가 있지만 ImageView에 setDrawable() 메서드가 없으므로 사용 방법이 표시되지 않습니다.

예제를 검색했습니다. 애니메이션과 회전 (특히 LunarLander)이 포함 된 이미지가 있지만 그 중 일부는 ImageView에 애니메이션을 적용한 다음 변형 된 상태로 남겨 두지 않습니다.

확실하게 나는 여기에서 간단한 것을 놓치고 있습니다 ... aaaargh, 어떻게 레이아웃 내에서 ImageView를 회전합니까?

감사합니다.

+0

90도를 추가하면 좋을 것입니다. 회전은 어느 정도의 각도가 될 수 있으므로 "각 이미지의 4 가지 버전 만들기 : 0, 90, 180 및 270도 회전"이 솔루션으로 작동하지 않습니다 ... –

답변

2

ImageView setImageDrawable은 이미지의 드로어 블을 구성합니다. 이렇게하면 ImageView 클래스를 사용할 수있게되어 Matrix 함수를 사용하게됩니다.

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; 
} 
} 
관련 문제