旋转和调整,在Android的单指图像视图 [英] rotate and resize the image view with single finger in android

查看:80
本文介绍了旋转和调整,在Android的单指图像视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个应用程序,它具有的功能,调整大小,并通过拖动右下角按钮旋转ImageView的。

我见过一个应用程序,它具有的功能,如果我们对角拖动右下角的按钮ImageView的大小调整了,否则,如果我们拖动按钮左侧或右侧方向的ImageView已旋转,每个方向。我希望在我的应用程序来实现此功能。

我奋力实现单指旋转以及调整大小ImageView的。

请指引我正确的方式。


我想这code,并尝试应用缩放和旋转,但没能做到,请帮助我。 belove code做缩放和旋转手指基地的行动。

 公共类ScaleActivity延伸活动{

的ViewGroup lLayout;
静态ImageView的IMG,backgrndImg;
帆布mCanvas;
浮D组;
私人浮动mAspectQuotient;
@覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);

    lLayout =(的FrameLayout)findViewById(R.id.lLayout);

    最后CropView CV =新CropView(本);
    lLayout.addView(CV);

}

@覆盖
公共布尔onCreateOptionsMenu(功能菜单){
    //充气菜单;这增加了项目操作栏,如果它是present。
    。getMenuInflater()膨胀(R.menu.main,菜单);
    返回true;
}

公共类CropView扩展ImageView的{
    私有静态最终诠释SELECTION_RECT_PAINT_COLOR = 0xFF000000;
    私有静态最终诠释SELECTION_RECT_FILL_COLOR = 0x70FFFFFF;
    私有静态最终诠释TOUCH_TOLERANCE = 25;
    私有静态最终诠释xInc = 25;
    私有静态最终诠释yInc = 25;
    涂料粉刷=新的油漆();
    私人诠释initial_size = 200;
    私人点leftTop,rightBottom,中心,previous,currentPoint,
            rectPos;
    私人油漆fillPaint;
    私人油漆rectPaint;
    受保护的矩形选择,DEST;
    私人布尔isAffectedBottom = FALSE;
    点阵位图,BackgroundBitmap指令;
    矩形rectf;
    矩形knobRect;
    私人语境mContext;
    INT宽度,高度;
    私人矩阵的矩阵=新的Matrix();
    位图resizedBitmap;

    //添加父类的构造函数
    公共CropView(上下文的背景下){
        超(上下文);

        mContext =背景;

        BackgroundBitmap指令= BitmapFactory.de codeResource(的getContext()
                .getResources(),R.drawable.toast_bkgrd);
        位= BitmapFactory.de codeResource(的getContext()。getResources()
                R.drawable.aviary_adjust_knob);

        rectPaint =新的油漆();
        rectPaint.setStyle(Style.STROKE);
        rectPaint.setColor(SELECTION_RECT_PAINT_COLOR);
        fillPaint =新的油漆();
        fillPaint.setStyle(Style.FILL);
        fillPaint.setColor(SELECTION_RECT_FILL_COLOR);
        currentPoint =新点(的getWidth()/ 2,的getHeight()/ 2);
        宽度= backgroundBitmap.getWidth();
        身高= backgroundBitmap.getHeight();
        initCropView();
    }

    公共CropView(上下文的背景下,ATTRS的AttributeSet){
        超级(上下文,ATTRS,0);
        initCropView();
    }

    公共CropView(上下文的背景下,ATTRS的AttributeSet,诠释defStyle){
        超(背景下,ATTRS,defStyle);
        initCropView();
    }

    @燮pressLint(DrawAllocation)
    @覆盖
    保护无效的OnDraw(帆布油画){
        super.onDraw(画布);
        mCanvas =帆布;
        如果(leftTop.equals(0,0))
            resetPoints();
        mCanvas.save();
        resizedBitmap = Bitmap.createBitmap(BackgroundBitmap指令,0,0,
                backgroundBitmap.getWidth(),backgroundBitmap.getHeight(),
                矩阵,真正的);
        // mCanvas.drawBitmap(BackgroundBitmap指令,矩阵,rectPaint);
        mCanvas.drawBitmap(resizedBitmap,空,选择,rectPaint);
        mCanvas.drawBitmap(位图,selection.right  -  25,
                selection.bottom  -  25,NULL);
        rectPos.set(selection.left,selection.top);

        mCanvas.restore();

    }


    @覆盖
    公共布尔的onTouchEvent(MotionEvent事件){
        INT eventaction = event.getAction();
        开关(eventaction){
        案例MotionEvent.ACTION_DOWN:
            达阵((INT)event.getX(),(INT)event.getY());
            previous.set((int)的event.getX(),(int)的event.getY());

            打破;
        案例MotionEvent.ACTION_MOVE:
            touchMove((int)的event.getX(),(int)的event.getY());

            如果(isActionInsideRectangle(event.getX(),event.getY())
                    &功放;&安培; !isAffectedBottom){
                拖动((int)的event.getX(),(int)的event.getY());
                无效(); //重新绘制矩形
                previous.set((int)的event.getX(),(int)的event.getY());
            }
            previous.set((int)的event.getX(),(int)的event.getY());
            打破;
        案例MotionEvent.ACTION_UP:
            触((int)的event.getX(),(int)的event.getY());
            previous =新的点();
            打破;
        }
        返回true;
    }

    私人无效initCropView(){
        paint.setColor(Color.WHITE);
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth(5);
        leftTop =新的点();
        rightBottom =新的点();
        中心=新的点();
        previous =新的点();
        rectPos =新的点();

    }

    公共无效resetPoints(){
        center.set(的getWidth()/ 2,的getHeight()/ 2);
        leftTop.set((的getWidth() -  initial_size)/ 2,
                (的getHeight() -  initial_size)/ 2);
        rightBottom.set(leftTop.x + initial_size,leftTop.y + initial_size);
        选择=新的矩形(leftTop.x,leftTop.y,rightBottom.x,
                rightBottom.y);
        knobRect =新的矩形(selection.right,selection.bottom,
                bitmap.getWidth(),bitmap.getHeight());
        DEST =选择;
    }

    私人布尔isActionInsideRectangle(浮X,浮动Y){
        INT缓冲= 10;
        则返回(x> =(selection.left)及&安培; X  - 其中=(selection.right)
                &功放;&安培; Y'GT; =(selection.top)及&安培; Y'LT; =(selection.bottom))?真正
                : 假;
    }

    无效达阵(INT X,int y)对{

        的System.out.println(选择+选择);
        INT DX =(previous.x  -  X)/ 2;
        INT DY =(previous.y  -  Y)/ 2;
        // D =旋转(DX,DY);
        currentPoint.set(X,Y​​);
        如果(pointsAreClose(X,Y,selection.right,selection.bottom)){
            isAffectedBottom = TRUE;
            的System.out.println(isAffectedBottom+ isAffectedBottom);
        }
    }

    无效touchMove(INT X,int y)对{
        currentPoint.set(X,Y​​);
        如果(isAffectedBottom){
            INT DX =(previous.x  -  X)/ 2;
            INT DY =(previous.y  -  Y)/ 2;
            双startAngle开始= getAngle(previous.x,previous.y);

            双currentAngle中= getAngle(X,Y);

            matrix.postRotate((浮动)(由startAngle  -  currentAngle中)
                    selection.width()/ 2.0f,selection.height()/ 2.0f);
            // selection.inset(DX,DY);
            无效();
        }
    }

    无效触(INT X,int y)对{
        currentPoint.set(X,Y​​);
        isAffectedBottom = FALSE;
    }

    私人布尔pointsAreClose(浮动X1,Y1浮球,浮球X2,浮动Y2){
        返回Math.hypot(X1  -  X2,Y1  -  y2)上与所述; TOUCH_TOLERANCE;
    }

    私人无效拖(INT X,int y)对{
        INT运动;
        运动= X  -  previous.x;
        INT movementY = Y  -  previous.y;
        selection.set(selection.left +运动,selection.top + movementY,
                selection.right +运动,selection.bottom + movementY);
        selection.sort();
        无效();
    }


    / **
     *计算由旋转的程度。
     *
     * @参数事件
     * @返回度
     * /
    //私人浮动旋转(浮动DX,浮动DY){
    //
    // //双delta_x =(DX);
    // //双delta_y =(DY);
    //双弧度= Math.atan2((selection.left) - (previous.y)
    //(selection.top) - (previous.x));
    //双radians2 = Math.atan2((selection.left) - (DY)
    //(selection.top) - (DX));
    //
    //的System.out.println(弧度+弧度);
    //的System.out.println(+ radians2);
    //的System.out.println(radians2弧度+(radians2  - 弧度));
    //的System.out.println(Math.toDegrees(radians2  - 弧度));
    //回报(浮)Math.toDegrees(radians2  - 弧度);
    //
    //}

    私人双人getAngle(双xTouch,双yTouch){
        双X = xTouch  - (的getWidth()/ 2D);
        双Y =的getHeight() -  yTouch  - (的getHeight()/ 2D);

        开关(getQuadrant(X,Y​​)){
        情况1:
            的System.out.println(1);
            返回Math.asin(γ/ Math.hypot(X,Y​​))* 180 / Math.PI;

        案例2:
        案例3:
            的System.out.println(32);
            返回180  - (Math.asin(Y / Math.hypot(X,Y​​))* 180 / Math.PI);

        壳体4:
            的System.out.println(4);
            返回360 + Math.asin(Y / Math.hypot(X,Y​​))* 180 / Math.PI;

        默认:
            //忽略,不会发生
            返回0;
        }
    }

    / **
     返回:所选的象限。
     * /
    私人诠释getQuadrant(双X,双Y){
        如果(X GT; = 0){
            返回是> = 0? 1:4;
        } 其他 {
            返回是> = 0? 2:3;
        }
    }
}

}
 

解决方案

请查看我创建的存储库中的GitHub的。

计数从中心点在旋转和缩放视图到按压点的距离。 只需使用:

 专用浮getDistance的(A点,B点){
    浮动V =((AX  -  BX)*(AX  -  BX))+((AY  - 由)*(AY  - 由));
    返回((int)的(的Math.sqrt(体积)* 100))/ 100F;
}
 

和算上OA / OB该值可以指望的观点新的高度和宽度

算的角度AOB中,A是先推一点,B是最后一个举动来看,O是观景点的中心。

和只需要设置新的高度和宽度的观点,并计算左侧和顶部视图。

烃源链接: https://github.com/ryanch741/android -view-旋转变焦单指

在code:

 点pushPoint;
INT lastImgWidth;
INT lastImgHeight;
INT lastImgLeft;
INT lastImgTop;
INT lastImgAngle;
双lastComAngle;

INT pushImgWidth;
INT pushImgHeight;

INT lastPushBtnLeft;
INT lastPushBtnTop;

私人查看MView的;
私人点mViewCenter;
私有静态最后双PI = 3.14159265359;

公共PushBtnTouchListener(查看MVIEW){
    this.mView = MView的;
}

私人FrameLayout.LayoutParams pushBtnLP;
私人FrameLayout.LayoutParams imgLP;
浮lastX = -1;
浮lastY = -1;

@覆盖
公共布尔onTouch(查看pushView,MotionEvent事件){
    开关(event.getAction()及MotionEvent.ACTION_MASK){
        //主点按下
        案例MotionEvent.ACTION_DOWN:
            pushBtnLP =(FrameLayout.LayoutParams)pushView.getLayoutParams();
            imgLP =(FrameLayout.LayoutParams)mView.getLayoutParams();

            pushPoint = getPushPoint(pushBtnLP,事件);
            lastImgWidth = imgLP.width;
            lastImgHeight = imgLP.height;
            lastImgLeft = imgLP.leftMargin;
            lastImgTop = imgLP.topMargin;
            lastImgAngle =(int)的mView.getRotation();

            lastPushBtnLeft = pushBtnLP.leftMargin;
            lastPushBtnTop = pushBtnLP.topMargin;

            pushImgWidth = pushBtnLP.width;
            pushImgHeight = pushBtnLP.height;
            lastX = event.getRawX();
            lastY = event.getRawY();
            refreshImageCenter();
            打破;
        //副点按下
        案例MotionEvent.ACTION_POINTER_DOWN:
            打破;
        案例MotionEvent.ACTION_UP:{
            打破;
        }
        案例MotionEvent.ACTION_POINTER_UP:
            打破;
        案例MotionEvent.ACTION_MOVE:
            浮rawX = event.getRawX();
            浮rawY = event.getRawY();
            如果(lastX!= -1){
                如果(Math.abs(rawX  -  lastX)小于5&安培;&安培; Math.abs(rawY  -  lastY)小于5){
                    返回false;
                }
            }
            lastX = rawX;
            lastY = rawY;

            点O = mViewCenter,A = pushPoint,B = getPushPoint(pushBtnLP,事件);
            浮DOA = getDistance的(O,A);
            浮DOB = getDistance的(O,B);
            浮动F = DOB / DOA;

            INT newWidth =(INT)(lastImgWidth * F);
            INT newHeight =(INT)(lastImgHeight * F);


            imgLP.leftMargin = lastImgLeft  - ((newWidth  -  lastImgWidth)/ 2);
            imgLP.topMargin = lastImgTop  - ((newHeight  -  lastImgHeight)/ 2);
            imgLP.width = newWidth;
            imgLP.height = newHeight;
            mView.setLayoutParams(imgLP);

            浮的fz =(((AX  - 牛)*(Bx的 - 牛))+((AY  -  Oy公司)*(由 -  Oy公司)));
            浮FM = DOA *出生日期;
            双comAngle =(180 * Math.acos(FZ / FM)/ PI);
            如果(Double.isNaN(comAngle)){
                comAngle =(lastComAngle< 90 || lastComAngle> 270)? 0:180;
            }否则如果((通过 -  Oy公司)*(斧 - 牛)≤(Ay的 -  Oy公司)*(Bx的 - 牛)){
                comAngle = 360  -  comAngle;
            }
            lastComAngle = comAngle;

            浮动角=(浮点)(lastImgAngle + comAngle);
            =角度%360;
            mView.setRotation(角度);
            点imageRB =新点(mView.getLeft()+ mView.getWidth(),mView.getTop()+ mView.getHeight());
            点anglePoint = getAnglePoint(O,imageRB,角度);

            pushBtnLP.leftMargin =(int)的(anglePoint.x  -  pushImgWidth / 2);
            pushBtnLP.topMargin =(int)的(anglePoint.y  -  pushImgHeight / 2);
            pushView.setLayoutParams(pushBtnLP);
            打破;
    }
    返回false;
}

私人无效refreshImageCenter(){
    INT X = mView.getLeft()+ mView.getWidth()/ 2;
    INT Y = mView.getTop()+ mView.getHeight()/ 2;
    mViewCenter =新点(X,Y);
}


私人点getPushPoint(FrameLayout.LayoutParams LP,MotionEvent事件){
    返回新的点(lp.leftMargin +(INT)event.getX(),lp.topMargin +(INT)event.getY());
}

私人浮动getDistance的(A点,B点){
    浮动V =((AX  -  BX)*(AX  -  BX))+((AY  - 由)*(AY  - 由));
    返回((int)的(的Math.sqrt(体积)* 100))/ 100F;
}

私人点getAnglePoint(点O,A点,浮动角){
    INT X,Y;
    浮DOA = getDistance的(O,A);
    双P1 =角度* PI / 180F;
    双P2 = Math.acos((A.x  -  O.x)/ DOA);
    X =(int)的(O.x + DOA * Math.cos(P1 + P2));

    双P3 = Math.acos((A.x  -  O.x)/ DOA);
    Y =(INT)(O.y + DOA * Math.sin(P1 + P3));
    返回新的点(X,Y);
}
 

I am developing an app which has feature that resizing and rotating the imageview by dragging its bottom right corner button.

I saw one app which has feature that if we drag the bottom right corner button diagonally imageview size had resized or else if we drag the button left or right side direction imageview had rotated as per direction. I wish to implement this feature in my app

I am struggling to implement single finger rotation as well as resizing the imageview.

Please guide me in right way.


I am trying this code, and try to apply zoom and rotate but not able to do please help me. belove code to do zoom and rotate finger base action.

public class ScaleActivity extends Activity {

ViewGroup lLayout;
static ImageView img, backgrndImg;
Canvas mCanvas;
float d;
private float mAspectQuotient;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lLayout = (FrameLayout) findViewById(R.id.lLayout);

    final CropView cv = new CropView(this);
    lLayout.addView(cv);

}

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

public class CropView extends ImageView {
    private static final int SELECTION_RECT_PAINT_COLOR = 0xFF000000;
    private static final int SELECTION_RECT_FILL_COLOR = 0x70FFFFFF;
    private static final int TOUCH_TOLERANCE = 25;
    private static final int xInc = 25;
    private static final int yInc = 25;
    Paint paint = new Paint();
    private int initial_size = 200;
    private Point leftTop, rightBottom, center, previous, currentPoint,
            rectPos;
    private Paint fillPaint;
    private Paint rectPaint;
    protected Rect selection, dest;
    private boolean isAffectedBottom = false;
    Bitmap bitmap, backgroundBitmap;
    Rect rectf;
    Rect knobRect;
    private Context mContext;
    int width, height;
    private Matrix matrix = new Matrix();
    Bitmap resizedBitmap;

    // Adding parent class constructors
    public CropView(Context context) {
        super(context);

        mContext = context;

        backgroundBitmap = BitmapFactory.decodeResource(getContext()
                .getResources(), R.drawable.toast_bkgrd);
        bitmap = BitmapFactory.decodeResource(getContext().getResources(),
                R.drawable.aviary_adjust_knob);

        rectPaint = new Paint();
        rectPaint.setStyle(Style.STROKE);
        rectPaint.setColor(SELECTION_RECT_PAINT_COLOR);
        fillPaint = new Paint();
        fillPaint.setStyle(Style.FILL);
        fillPaint.setColor(SELECTION_RECT_FILL_COLOR);
        currentPoint = new Point(getWidth() / 2, getHeight() / 2);
        width = backgroundBitmap.getWidth();
        height = backgroundBitmap.getHeight();
        initCropView();
    }

    public CropView(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
        initCropView();
    }

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

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mCanvas = canvas;
        if (leftTop.equals(0, 0))
            resetPoints();
        mCanvas.save();
        resizedBitmap = Bitmap.createBitmap(backgroundBitmap, 0, 0,
                backgroundBitmap.getWidth(), backgroundBitmap.getHeight(),
                matrix, true);
        // mCanvas.drawBitmap(backgroundBitmap, matrix, rectPaint);
        mCanvas.drawBitmap(resizedBitmap, null, selection, rectPaint);
        mCanvas.drawBitmap(bitmap, selection.right - 25,
                selection.bottom - 25, null);
        rectPos.set(selection.left, selection.top);

        mCanvas.restore();

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int eventaction = event.getAction();
        switch (eventaction) {
        case MotionEvent.ACTION_DOWN:
            touchDown((int) event.getX(), (int) event.getY());
            previous.set((int) event.getX(), (int) event.getY());

            break;
        case MotionEvent.ACTION_MOVE:
            touchMove((int) event.getX(), (int) event.getY());

            if (isActionInsideRectangle(event.getX(), event.getY())
                    && !isAffectedBottom) {
                drag((int) event.getX(), (int) event.getY());
                invalidate(); // redraw rectangle
                previous.set((int) event.getX(), (int) event.getY());
            }
            previous.set((int) event.getX(), (int) event.getY());
            break;
        case MotionEvent.ACTION_UP:
            touchUp((int) event.getX(), (int) event.getY());
            previous = new Point();
            break;
        }
        return true;
    }

    private void initCropView() {
        paint.setColor(Color.WHITE);
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth(5);
        leftTop = new Point();
        rightBottom = new Point();
        center = new Point();
        previous = new Point();
        rectPos = new Point();

    }

    public void resetPoints() {
        center.set(getWidth() / 2, getHeight() / 2);
        leftTop.set((getWidth() - initial_size) / 2,
                (getHeight() - initial_size) / 2);
        rightBottom.set(leftTop.x + initial_size, leftTop.y + initial_size);
        selection = new Rect(leftTop.x, leftTop.y, rightBottom.x,
                rightBottom.y);
        knobRect = new Rect(selection.right, selection.bottom,
                bitmap.getWidth(), bitmap.getHeight());
        dest = selection;
    }

    private boolean isActionInsideRectangle(float x, float y) {
        int buffer = 10;
        return (x >= (selection.left) && x <= (selection.right)
                && y >= (selection.top) && y <= (selection.bottom)) ? true
                : false;
    }

    void touchDown(int x, int y) {

        System.out.println("selection " + selection);
        int dx = (previous.x - x) / 2;
        int dy = (previous.y - y) / 2;
        // d= rotation(dx,dy);
        currentPoint.set(x, y);
        if (pointsAreClose(x, y, selection.right, selection.bottom)) {
            isAffectedBottom = true;
            System.out.println("isAffectedBottom " + isAffectedBottom);
        }
    }

    void touchMove(int x, int y) {
        currentPoint.set(x, y);
        if (isAffectedBottom) {
            int dx = (previous.x - x) / 2;
            int dy = (previous.y - y) / 2;
            double startAngle = getAngle(previous.x, previous.y);

            double currentAngle = getAngle(x, y);

            matrix.postRotate((float) (startAngle - currentAngle),
                    selection.width() / 2.0f, selection.height() / 2.0f);
            // selection.inset(dx, dy);             
            invalidate();
        }
    }

    void touchUp(int x, int y) {
        currentPoint.set(x, y);
        isAffectedBottom = false;
    }

    private boolean pointsAreClose(float x1, float y1, float x2, float y2) {
        return Math.hypot(x1 - x2, y1 - y2) < TOUCH_TOLERANCE;
    }

    private void drag(int x, int y) {
        int movement;
        movement = x - previous.x;
        int movementY = y - previous.y;
        selection.set(selection.left + movement, selection.top + movementY,
                selection.right + movement, selection.bottom + movementY);
        selection.sort();
        invalidate();
    }


    /**
     * Calculate the degree to be rotated by.
     * 
     * @param event
     * @return Degrees
     */
    // private float rotation(float dx, float dy) {
    //
    // // double delta_x = (dx);
    // // double delta_y = (dy);
    // double radians = Math.atan2((selection.left) - (previous.y),
    // (selection.top) - (previous.x));
    // double radians2 = Math.atan2((selection.left) - (dy),
    // (selection.top) - (dx));
    //
    // System.out.println("radians" + radians);
    // System.out.println("" + radians2);
    // System.out.println("radians2-radians" + (radians2 - radians));
    // System.out.println(Math.toDegrees(radians2 - radians));
    // return (float) Math.toDegrees(radians2 - radians);
    //
    // }

    private double getAngle(double xTouch, double yTouch) {
        double x = xTouch - (getWidth() / 2d);
        double y = getHeight() - yTouch - (getHeight() / 2d);

        switch (getQuadrant(x, y)) {
        case 1:
            System.out.println("1");
            return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;

        case 2:
        case 3:
            System.out.println("32");
            return 180 - (Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);

        case 4:
            System.out.println("4");
            return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;

        default:
            // ignore, does not happen
            return 0;
        }
    }

    /**
     * @return The selected quadrant.
     */
    private int getQuadrant(double x, double y) {
        if (x >= 0) {
            return y >= 0 ? 1 : 4;
        } else {
            return y >= 0 ? 2 : 3;
        }
    }
}

}

解决方案

please check the repository in github i create it .

count the distance from center point in the rotate and zoom view to the push point. just use :

 private float getDistance(Point a, Point b) {
    float v = ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));
    return ((int) (Math.sqrt(v) * 100)) / 100f;
}

and count the OA/OB that value can count the view new height and width

count the angle AOB, the A is the first push point , the B is the last move point ,the O is the center of the View Point .

and then just set new height and width for view ,and count the left and top for view .

souce link : https://github.com/ryanch741/android-view-rotate-zoom-single-finger

the code:

    Point pushPoint;
int lastImgWidth;
int lastImgHeight;
int lastImgLeft;
int lastImgTop;
int lastImgAngle;
double lastComAngle;

int pushImgWidth;
int pushImgHeight;

int lastPushBtnLeft;
int lastPushBtnTop;

private View mView;
private Point mViewCenter;
private static final double PI = 3.14159265359;

public PushBtnTouchListener(View mView) {
    this.mView = mView;
}

private FrameLayout.LayoutParams pushBtnLP;
private FrameLayout.LayoutParams imgLP;
float lastX = -1;
float lastY = -1;

@Override
public boolean onTouch(View pushView, MotionEvent event) {
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        // 主点按下
        case MotionEvent.ACTION_DOWN:
            pushBtnLP = (FrameLayout.LayoutParams) pushView.getLayoutParams();
            imgLP = (FrameLayout.LayoutParams) mView.getLayoutParams();

            pushPoint = getPushPoint(pushBtnLP, event);
            lastImgWidth = imgLP.width;
            lastImgHeight = imgLP.height;
            lastImgLeft = imgLP.leftMargin;
            lastImgTop = imgLP.topMargin;
            lastImgAngle = (int) mView.getRotation();

            lastPushBtnLeft = pushBtnLP.leftMargin;
            lastPushBtnTop = pushBtnLP.topMargin;

            pushImgWidth = pushBtnLP.width;
            pushImgHeight = pushBtnLP.height;
            lastX = event.getRawX();
            lastY = event.getRawY();
            refreshImageCenter();
            break;
        // 副点按下
        case MotionEvent.ACTION_POINTER_DOWN:
            break;
        case MotionEvent.ACTION_UP: {
            break;
        }
        case MotionEvent.ACTION_POINTER_UP:
            break;
        case MotionEvent.ACTION_MOVE:
            float rawX = event.getRawX();
            float rawY = event.getRawY();
            if (lastX != -1) {
                if (Math.abs(rawX - lastX) < 5 && Math.abs(rawY - lastY) < 5) {
                    return false;
                }
            }
            lastX = rawX;
            lastY = rawY;

            Point O = mViewCenter, A = pushPoint, B = getPushPoint(pushBtnLP, event);
            float dOA = getDistance(O, A);
            float dOB = getDistance(O, B);
            float f = dOB / dOA;

            int newWidth = (int) (lastImgWidth * f);
            int newHeight = (int) (lastImgHeight * f);


            imgLP.leftMargin = lastImgLeft - ((newWidth - lastImgWidth) / 2);
            imgLP.topMargin = lastImgTop - ((newHeight - lastImgHeight) / 2);
            imgLP.width = newWidth;
            imgLP.height = newHeight;
            mView.setLayoutParams(imgLP);

            float fz = (((A.x - O.x) * (B.x - O.x)) + ((A.y - O.y) * (B.y - O.y)));
            float fm = dOA * dOB;
            double comAngle = (180 * Math.acos(fz / fm) / PI);
            if (Double.isNaN(comAngle)) {
                comAngle = (lastComAngle < 90 || lastComAngle > 270) ? 0 : 180;
            } else if ((B.y - O.y) * (A.x - O.x) < (A.y - O.y) * (B.x - O.x)) {
                comAngle = 360 - comAngle;
            }
            lastComAngle = comAngle;

            float angle = (float) (lastImgAngle + comAngle);
            angle = angle % 360;
            mView.setRotation(angle);
            Point imageRB = new Point(mView.getLeft() + mView.getWidth(), mView.getTop() + mView.getHeight());
            Point anglePoint = getAnglePoint(O, imageRB, angle);

            pushBtnLP.leftMargin = (int) (anglePoint.x - pushImgWidth / 2);
            pushBtnLP.topMargin = (int) (anglePoint.y - pushImgHeight / 2);
            pushView.setLayoutParams(pushBtnLP);
            break;
    }
    return false;
}

private void refreshImageCenter() {
    int x = mView.getLeft() + mView.getWidth() / 2;
    int y = mView.getTop() + mView.getHeight() / 2;
    mViewCenter = new Point(x, y);
}


private Point getPushPoint(FrameLayout.LayoutParams lp, MotionEvent event) {
    return new Point(lp.leftMargin + (int) event.getX(), lp.topMargin + (int) event.getY());
}

private float getDistance(Point a, Point b) {
    float v = ((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y));
    return ((int) (Math.sqrt(v) * 100)) / 100f;
}

private Point getAnglePoint(Point O, Point A, float angle) {
    int x, y;
    float dOA = getDistance(O, A);
    double p1 = angle * PI / 180f;
    double p2 = Math.acos((A.x - O.x) / dOA);
    x = (int) (O.x + dOA * Math.cos(p1 + p2));

    double p3 = Math.acos((A.x - O.x) / dOA);
    y = (int) (O.y + dOA * Math.sin(p1 + p3));
    return new Point(x, y);
}

这篇关于旋转和调整,在Android的单指图像视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆