Поворот ImageView в макете ... как? - PullRequest
3 голосов
/ 03 февраля 2010

У меня есть макет с изображением на нем (встроенный в 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 (или базовый объект рисования) и, возможно, сделать его недействительным, чтобы вызвать перерисовку.

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

Я пытался использовать getImageMatix / setImageMatrix на mImageView, без видимого эффекта. Существуют подклассы Drawable, которые будут вращать изображение, но в ImageView нет метода setDrawable (), поэтому я не вижу, как его использовать.

Я искал примеры; хотя некоторые из них включают анимацию и вращение (особенно LunarLander), ни один из них не анимирует ImageView, а затем оставляет его в каком-то преобразованном состоянии.

Конечно, я упускаю что-то простое здесь ... ааааааа, как вы поворачиваете ImageView в макете?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2010

ImageView setImageDrawable настроит рисование в изображении.Это должно позволить вам использовать класс ImageView и, следовательно, использовать функции Matrix для этого.

0 голосов
/ 26 июня 2014

Попробуйте этот 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;
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...