【问题标题】:Rotating an ImageView within a Layout... how?在布局中旋转 ImageView ......如何?
【发布时间】:2010-02-03 08:54:22
【问题描述】:

我有一个带有图像的布局(嵌入在 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);
    }
}

图像平滑地旋转 90 度,但随后又恢复到原始状态。这就是 Android 文档所说的动画完成后会发生的事情。据推测,在动画结束的通知中,我应该转换 ImageView(或底层可绘制对象),并可能使其无效以触发重绘。

一切都很好,除了我找不到方法,也找不到任何其他人这样做的例子

我尝试在mImageView 上使用getImageMatix/setImageMatrix,但没有明显效果。 Drawable 的子类可以旋转图像,但是 ImageView 上没有 setDrawable() 方法,所以我不知道如何使用。

我搜索了示例;尽管其中一些涉及动画和旋转(尤其是 LunarLander),但它们都没有为 ImageView 设置动画,然后将其置于某种变换状态。

我肯定在这里遗漏了一些简单的东西...... aaaargh,你如何在布局中旋转 ImageView?

谢谢。

【问题讨论】:

  • 我应该补充一点,90 度只是一个很好的圆形示例。旋转可以是任意度数,因此“为每个图像制作四个版本:0、90、180 和 270 度旋转”并不能作为解决方案......

标签: android


【解决方案1】:

ImageView setImageDrawable 将在 Image 中配置 drawable。这应该允许您使用 ImageView 类,从而在其上使用 Matrix 函数。

【讨论】:

    【解决方案2】:

    试试这个 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;
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      相关资源
      最近更新 更多