Android的ImageView的缩放,旋转,位置变化的概率缩放、概率、位置、Android

2023-09-04 23:18:32 作者:无敌小萌神

我使用的是下面的code的形象,这将旋转,放大,用捏。用户可以通过拖动它使自己的立场。

I am using a the following code for a image, which will rotate, zoom in-out with pinch. User can make its position by dragging it.

activity_img_match.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@drawable/brokenbone"
        android:gravity="center_vertical|center_horizontal" >

        <ImageView
            android:id="@+id/bonestruct"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:scaleType="matrix"
            android:src="@drawable/bone" />
    </FrameLayout>

ImgMatchActivity.java

    public class ImgMatchActivity extends Activity implements OnTouchListener {

    private static final String TAG = "Touch";
    // These matrices will be used to move and zoom image
    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();
    Matrix savedMatrix2 = new Matrix();

    // We can be in one of these 3 states
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    private static final float MAX_ZOOM = 5.0f;
    private static final float MIN_ZOOM = 0.15f;
    int mode = NONE;

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

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

        ImageView bonestruct = (ImageView) findViewById(R.id.bonestruct);
        bonestruct.setOnTouchListener(this);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_img_match, menu);
        return true;
    }

    public boolean onTouch(View selectedView, MotionEvent event) {
        // TODO Auto-generated method stub
        ImageView view = (ImageView) selectedView;
        int rotation = 25;
        // Dump touch event to log
        dumpEvent(event);

        // Handle touch events here...
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            savedMatrix.set(matrix);
            start.set(event.getX(), event.getY());
            Log.d(TAG, "mode=DRAG");
            mode = DRAG;
            break;

        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            Log.d(TAG, "oldDist=" + oldDist);
            if (oldDist > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
                Log.d(TAG, "mode=ZOOM");
            }
            break;

        case MotionEvent.ACTION_UP:

            mode = NONE;
            Log.d(TAG, "mode=NONE");
            savedMatrix.set(matrix);
            //matrix.postRotate(90);

            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) {
                float newDist = spacing(event);
                Log.d(TAG, "newDist=" + newDist);
                if (newDist > 10f) {
                    matrix.set(savedMatrix);
                    float scale = newDist / oldDist;
                    matrix.postScale(scale, scale, mid.x, mid.y);
                }
            }
            break;
        }

        view.setImageMatrix(matrix);
        fixing();
        view.setImageMatrix(savedMatrix2);

        return true; // indicate event was handled

    }

    public void fixing() {

        float[] value = new float[9];
        matrix.getValues(value);

        float[] savedValue = new float[9];
        savedMatrix.getValues(savedValue);

        WindowManager mWinMgr = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
        int width = mWinMgr.getDefaultDisplay().getWidth();
        int height = mWinMgr.getDefaultDisplay().getHeight();

        Drawable d = this.getResources().getDrawable(R.drawable.bone);
        if (d == null)
            return;
        int imageWidth = d.getIntrinsicWidth();
        int imageHeight = d.getIntrinsicHeight();
        int scaleWidth = (int) (imageWidth * value[0]);
        int scaleHeight = (int) (imageHeight * value[4]);

        // don't let the image go outside
        if (value[2] > width - 1)
            value[2] = width - 10;
        else if (value[5] > height - 1)
            value[5] = height - 10;
        else if (value[2] < -(scaleWidth - 1))
            value[2] = -(scaleWidth - 10);
        else if (value[5] < -(scaleHeight - 1))
            value[5] = -(scaleHeight - 10);

        //Log.d("value[0]", "value[0]: "+value[0]);
        //Log.d("value[4]", "value[4]: "+value[4]);

        // maximum zoom ratio: MAX
        if (value[0] > MAX_ZOOM || value[4] > MAX_ZOOM) {
            value[0] = MAX_ZOOM;
            value[4] = MAX_ZOOM;
            // value[2] = savedValue[2];
            // value[5] = savedValue[5];
        }

        // minimum zoom ratio: MIN
        /*if (value[0] < MIN_ZOOM || value[4] < MIN_ZOOM) {
            value[0] = MIN_ZOOM;
            value[4] = MIN_ZOOM;
            // value[2] = savedValue[2];
            // value[5] = savedValue[5];
        }*/

        matrix.setValues(value);
        savedMatrix2.set(matrix);
    }

    /** Show an event in the LogCat view, for debugging */
    private void dumpEvent(MotionEvent event) {
        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
        StringBuilder sb = new StringBuilder();
        int action = event.getAction();
        int actionCode = action & MotionEvent.ACTION_MASK;
        sb.append("event ACTION_").append(names[actionCode]);
        if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                || actionCode == MotionEvent.ACTION_POINTER_UP) {
            sb.append("(pid ").append(
                    action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
            sb.append(")");
        }
        sb.append("[");
        for (int i = 0; i < event.getPointerCount(); i++) {
            sb.append("#").append(i);
            sb.append("(pid ").append(event.getPointerId(i));
            sb.append(")=").append((int) event.getX(i));
            sb.append(",").append((int) event.getY(i));
            if (i + 1 < event.getPointerCount())
                sb.append(";");
        }
        sb.append("]");
        Log.d(TAG, sb.toString());
    }

    /** Determine the space between the first two fingers */
    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);
    }

    /** Calculate the mid point of the first two fingers */
    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);
    }

}

现在我可以拖动图像,放大它,通过捏动作。但没有旋转可言。如何获得的转动操作和获得旋转角θ

Now I can drag the image, zoom it-out by pinch action. But there is no rotation at all. How to get the rotation action and get rotation angle?

推荐答案

试着用code以下的工作对我来说。

Try with below code its working for me.

float[] lastEvent = null;
float d = 0f;
float newRot = 0f;

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

//有关多点触控旋转图像。

//For rotate image on multi-touch.

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