转动转盘有限度 [英] rotate dial in limited degrees

查看:146
本文介绍了转动转盘有限度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所有
我想旋转图像在特定的角度像下面的图像。我有$ C $下旋转,但其旋转360度,但我想它只有在特定的学位,并获得选择的号码是表盘上侧。


下面是我的code。 我的自定义视图这个做工精细性能比较,但湖泊。

 进口android.content.Context;
进口android.graphics.Bitmap;
进口android.graphics.BitmapFactory;
进口android.graphics.Canvas;
进口android.graphics.Paint;
进口android.graphics.PointF;
进口android.graphics.Rect;
进口android.util.AttributeSet;
进口android.util.Log;
进口android.view.GestureDetector.OnGestureListener;
进口android.view.GestureDetector;
进口android.view.MotionEvent;
进口android.view.View;

公共类MyDialView扩展视图实现OnGestureListener {
    私有静态位图bimmap;
    私人静电涂料粉刷;
    私有静态矩形边界;
    私人诠释totalNicks = 100;
    私人诠释currentNick = 0;
    私人GestureDetector gestureDetector;
    私人浮动dragStartDeg =的Float.NaN;
    浮dialerWidth = 0,dialerHeight = 0;

    私人静电漆createDefaultPaint(){
        涂料粉刷=新的油漆();
        paint.setAntiAlias​​(真正的);
        paint.setFilterBitmap(真正的);
        返回漆;
    }
    私人浮动xyToDegrees(浮X,浮动Y){
        浮distanceFromCenter = PointF.length((X  -  0.5F),(Y  -  0.5F));
        如果(distanceFromCenter< 0.1F
                || distanceFromCenter> 0.5F){//忽略中心和出界事件
            返回的Float.NaN;
        } 其他 {
            返回(浮动)Math.toDegrees(Math.atan2(X  -  0.5F,Y  -  0.5F));
        }
    }
    公众最终浮getRotationInDegrees(){
        返程(360.0f / totalNicks)* currentNick;
    }

    公众最终无效旋转(INT缺口){
        currentNick =(currentNick +划痕);
        如果(currentNick> = totalNicks){
            currentNick%= totalNicks;
        }否则如果(currentNick℃,){
            currentNick =(totalNicks + currentNick);
        }
        Log.e(当前缺口,将String.valueOf(currentNick));
        如果((currentNick> 80 || currentNick小于20)){
            无效();
        }
    }
    公共MyDialView(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
        bimmap = BitmapFactory.de codeResource(context.getResources(),R.drawable.out_round);
        油漆= createDefaultPaint();
        gestureDetector =新GestureDetector(的getContext(),这一点);
        dialerWidth = bimmap.getWidth()/2.0f;
        dialerHeight = bimmap.getHeight()/ 2.0f;
        边界=新的矩形();
    }



    @覆盖
    保护无效的OnDraw(帆布油画){
        canvas.getClipBounds(边界);
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            // {
                canvas.translate(bounds.left,bounds.top);

                浮旋转= getRotationInDegrees();
                canvas.rotate(旋转,dialerWidth,dialerHeight);
                canvas.drawBitmap(bimmap,0,0,NULL);
                //canvas.rotate(-旋转,dialerWidth,dialerHeight);
            //}
            canvas.restore();
    }
    @覆盖
    公共布尔的onTouchEvent(MotionEvent事件){
        如果(gestureDetector.onTouchEvent(事件)){
            返回true;
        } 其他 {
            返回super.onTouchEvent(事件);
        }
    }
    //手势检测方法
    @覆盖
    公共布尔onDown(MotionEvent E){
        浮动X = e.getX()/((浮动)的getWidth());
        浮动Y = e.getY()/((浮动)的getHeight());

        dragStartDeg = xyToDegrees(X,Y);
        //Log.d("deg =,+ dragStartDeg);
        如果(!Float.isNaN(dragStartDeg)){
            返回true;
        } 其他 {
            返回false;
        }
    }

    @覆盖
    公共布尔onFling(MotionEvent E1,E2 MotionEvent,浮velocityX,
            浮动velocityY){
        返回false;
    }

    @覆盖
    公共无效onLong preSS(MotionEvent E){

    }

    @覆盖
    公共布尔onScroll(MotionEvent E1,E2 MotionEvent,浮distanceX,
            浮动distanceY){
        如果(!Float.isNaN(dragStartDeg)){
            浮currentDeg = xyToDegrees(e2.getX()/的getWidth(),
                    e2.getY()/的getHeight());

            如果(!Float.isNaN(currentDeg)){
                浮degPerNick = 360.0f / totalNicks;
                浮deltaDeg = dragStartDeg  -  currentDeg;

                最终诠释缺口=(INT)(Math.signum(deltaDeg)
                        * Math.floor(Math.abs(deltaDeg)/ degPerNick));

                如果(刻痕!= 0){
                    dragStartDeg = currentDeg;
                    旋转(缺口);
                }
            }

            返回true;
        } 其他 {
            返回false;
        }
    }

    @覆盖
    公共无效OnShow中preSS(MotionEvent E){

    }

    @覆盖
    公共布尔onSingleTapUp(MotionEvent E){
        返回false;
    }

}
 


我想0-9,根据用户的选择和放大器;还允许用户旋转0-9不转动。

我也检查另外code这是下文。

 拨号=(ImageView的)findViewById(R.id.imageView_ring);
        dialer.setOnTouchListener(新MyOnTouchListener());
        dialer.getViewTreeObserver()。addOnGlobalLayoutListener(新OnGlobalLayoutListener(){

            @覆盖
            公共无效onGlobalLayout(){
                //方法调用一次以上,但这些值只需要初始化一次
                如果(dialerHeight == 0 || dialerWidth == 0){
                    dialerHeight = dialer.getHeight();
                    dialerWidth = dialer.getWidth();

                    //调整
                    矩阵调整大小=新的Matrix();
                    resize.postScale((浮点)Math.min(dialerWidth,dialerHeight)/(浮点)imageOriginal.getWidth(),(浮动)Math.min(dialerWidth,dialerHeight)/(浮点)imageOriginal.getHeight());
                    imageScaled = Bitmap.createBitmap(imageOriginal,0,0,imageOriginal.getWidth(),imageOriginal.getHeight(),调整大小,FALSE);

                    //转换为图像视图的中心
                    浮translateX = dialerWidth / 2  -  imageScaled.getWidth()/ 2;
                    浮translateY = dialerHeight / 2  -  imageScaled.getHeight()/ 2;
                    matrix.postTranslate(translateX,translateY);

                    dialer.setImageBitmap(imageScaled);
                    dialer.setImageMatrix(矩阵);
                    Log.e(旋转角度:+ rotationDegrees,将String.valueOf(tickNumber));
                }
            }
        });

INT tickNumber = 0;
    私人无效rotateDialer(浮度){

        //System.out.println("Rotation完成::+ rotationDone);

       //如果(!rotationDone){

            this.rotationDegrees + =度;
            this.rotationDegrees = this.rotationDegrees%360;

            tickNumber =(int)的this.rotationDegrees * 100/360产品;
            //这可能是负
            如果(tickNumber大于0)tickNumber = 100  -  tickNumber;


            //this.rotationDegrees = Math.abs(rotationDegrees);
            this.tickNumber = Math.abs(tickNumber);

           如果(tickNumber小于20 || tickNumber> 80){
               Log.e(旋转角度:+ rotationDegrees,将String.valueOf(tickNumber));
               matrix.postRotate(度,dialerWidth / 2,dialerHeight / 2);
               dialer.setImageMatrix(矩阵);
           }

       //}
    }
    / **
     返回:单位圆与图像视图的中心的角度
     * /
    私人双人getAngle(双xTouch,双yTouch){

        双delta_x = xTouch  - (dialerWidth)/ 2;
        双delta_y =(dialerHeight)/ 2  -  yTouch;
        双弧度= Math.atan2(delta_y,delta_x);

        双DX = xTouch  -  DWIDTH;
        双DY =(dHeight  - ((dialerHeight)/ 2)) -  yTouch;
        双dRadi = Math.atan2(DY,DX);
        //Log.e("MY度,将String.valueOf(Math.toDegrees(dRadi)));
        //返回Math.toDegrees(dRadi);
        返回Math.toDegrees(弧度);
    }



    / **
     *简单的实现了{@link OnTouchListener}的注册拨号器的触摸事件。
     * /
    私有类MyOnTouchListener实现OnTouchListener {

        私人双人startAngle开始;

        @覆盖
        公共布尔onTouch(视图V,MotionEvent事件){

            开关(event.getAction()){

                案例MotionEvent.ACTION_DOWN:

                    //重新设置感动象限
                    / *的for(int i = 0; I< quadrantTouched.length;我++){
                        quadrantTouched [我] = FALSE;
                    } * /

                    // allowRotating = FALSE;

                    由startAngle = getAngle(event.getX(),event.getY());
                    打破;

                案例MotionEvent.ACTION_MOVE:
                    / *双rotationAngleRadians = Math.atan2(event.getX() - (dialer.getWidth()/ 2),((dialer.getHeight()/ 2) -  event.getY()));
                    双角=(INT)Math.toDegrees(rotationAngleRadians);
                    Log.i(GG,rotaion角+角); * /

                    双currentAngle中= getAngle(event.getX(),event.getY());
                    //如果(currentAngle中< 130 || currentAngle中< 110){
                        //Log.e("Start角度:+ startAngle开始,当前角度+ currentAngle中);
                        rotateDialer((浮动)(由startAngle  -  currentAngle中));
                        由startAngle = currentAngle中;
                    //}


                    //Log.e("MOVE启动度:+ startAngle开始,当前等级:+ currentAngle中);
                    打破;

                案例MotionEvent.ACTION_UP:
                    // allowRotating = TRUE;
                    打破;
            }

            //设置触摸象限为真
            // quadrantTouched [getQuadrant(event.getX() - (dialerWidth / 2),dialerHeight  -  event.getY() - (dialerHeight / 2))] =真;

            //detector.onTouchEvent(event);

            返回true;
        }
    }
 

解决方案

喜吉里什还有一类命名的 RotateAnimation 通过使用这个U类可以很容易地做到这一点。

 看起来像示例

      RotateAnimation R =新RotateAnimation(0F,-90f,200,200); // 这里
      r.setStartOffset(1000);
      r.setDuration(1000);
      r.setFillAfter(真正的); //这里
      animationSet.addAnimation(r)的;
 

All
I want rotate image in particular angle as like below image. I have code for rotation but it rotate 360 degree but I want it only for particular degrees and get the selected number which is upper side of dial.


below is my code. My custom View this work fine but lake of perfomance.

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class MyDialView extends View implements OnGestureListener{
    private static Bitmap bimmap;
    private static Paint paint;
    private static Rect bounds;
    private int totalNicks = 100;
    private int currentNick = 0;
    private GestureDetector gestureDetector;
    private float dragStartDeg = Float.NaN;
    float dialerWidth = 0,dialerHeight = 0;

    private static Paint createDefaultPaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        return paint;
    }
    private float xyToDegrees(float x, float y) {
        float distanceFromCenter = PointF.length((x - 0.5f), (y - 0.5f));
        if (distanceFromCenter < 0.1f
                || distanceFromCenter > 0.5f) { // ignore center and out of bounds events
            return Float.NaN;
        } else {
            return (float) Math.toDegrees(Math.atan2(x - 0.5f, y - 0.5f));
        }
    }
    public final float getRotationInDegrees() {
        return (360.0f / totalNicks) * currentNick;
    }

    public final void rotate(int nicks) {
        currentNick = (currentNick + nicks);
        if (currentNick >= totalNicks) {
            currentNick %= totalNicks;
        } else if (currentNick < 0) {
            currentNick = (totalNicks + currentNick);
        }
        Log.e("Current nick", String.valueOf(currentNick));
        if((currentNick > 80 || currentNick < 20)){
            invalidate();
        }
    }
    public MyDialView(Context context, AttributeSet attrs) {
        super(context, attrs);
        bimmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.out_round);
        paint = createDefaultPaint();
        gestureDetector = new GestureDetector(getContext(), this);
        dialerWidth = bimmap.getWidth() /2.0f;
        dialerHeight = bimmap.getHeight() / 2.0f;
        bounds = new Rect();
    }



    @Override
    protected void onDraw(Canvas canvas) {
        canvas.getClipBounds(bounds);
            canvas.save(Canvas.MATRIX_SAVE_FLAG);
            //{
                canvas.translate(bounds.left, bounds.top);

                float rotation = getRotationInDegrees();
                canvas.rotate(rotation, dialerWidth, dialerHeight);
                canvas.drawBitmap(bimmap, 0,0,null);
                //canvas.rotate(- rotation, dialerWidth, dialerHeight);
            //}     
            canvas.restore();
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (gestureDetector.onTouchEvent(event)) {
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }
    //Gesture detector methods
    @Override
    public boolean onDown(MotionEvent e) {
        float x = e.getX() / ((float) getWidth());
        float y = e.getY() / ((float) getHeight());

        dragStartDeg = xyToDegrees(x, y);
        //Log.d("deg = " , ""+dragStartDeg);
        if (! Float.isNaN(dragStartDeg)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        if (! Float.isNaN(dragStartDeg)) {
            float currentDeg = xyToDegrees(e2.getX() / getWidth(), 
                    e2.getY() / getHeight());

            if (! Float.isNaN(currentDeg)) {
                float degPerNick = 360.0f / totalNicks;
                float deltaDeg = dragStartDeg - currentDeg;

                final int nicks = (int) (Math.signum(deltaDeg) 
                        * Math.floor(Math.abs(deltaDeg) / degPerNick));

                if (nicks != 0) {
                    dragStartDeg = currentDeg;
                    rotate(nicks);
                } 
            } 

            return true;
        } else {
            return false;
        }
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

}


I want 0-9 according to user selection & also allow user rotation to 0-9 not more rotation.

I have also check another code this is below.

dialer = (ImageView) findViewById(R.id.imageView_ring);
        dialer.setOnTouchListener(new MyOnTouchListener());
        dialer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                // method called more than once, but the values only need to be initialized one time
                if (dialerHeight == 0 || dialerWidth == 0) {
                    dialerHeight = dialer.getHeight();
                    dialerWidth = dialer.getWidth();

                    // resize
                    Matrix resize = new Matrix();
                    resize.postScale((float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getWidth(), (float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getHeight());
                    imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false);

                    // translate to the image view's center
                    float translateX = dialerWidth / 2 - imageScaled.getWidth() / 2;
                    float translateY = dialerHeight / 2 - imageScaled.getHeight() / 2;
                    matrix.postTranslate(translateX, translateY);

                    dialer.setImageBitmap(imageScaled);
                    dialer.setImageMatrix(matrix);
                    Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber));
                }
            }
        });

int tickNumber = 0;
    private void rotateDialer(float degrees) {

        //System.out.println("Rotation Done :: "+rotationDone);

       // if(!rotationDone) {

            this.rotationDegrees += degrees;
            this.rotationDegrees = this.rotationDegrees % 360;

            tickNumber = (int)this.rotationDegrees*100/360;
            // It could be negative
            if (tickNumber > 0) tickNumber = 100 - tickNumber;


            //this.rotationDegrees  = Math.abs(rotationDegrees);
            this.tickNumber = Math.abs(tickNumber);

           if(tickNumber  < 20 || tickNumber > 80){
               Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber));
               matrix.postRotate(degrees, dialerWidth / 2, dialerHeight / 2);
               dialer.setImageMatrix(matrix);
           }

       // }
    }
    /**
     * @return The angle of the unit circle with the image view's center
     */
    private double getAngle(double xTouch, double yTouch) {

        double delta_x = xTouch - (dialerWidth) /2;
        double delta_y = (dialerHeight) /2 - yTouch;
        double radians = Math.atan2(delta_y, delta_x);

        double dx = xTouch - dWidth;
        double dy = (dHeight - ((dialerHeight) /2)) -  yTouch;
        double dRadi = Math.atan2(dy, dx);
        //Log.e("MY degree", String.valueOf( Math.toDegrees(dRadi)));
        //return Math.toDegrees(dRadi);
        return Math.toDegrees(radians);
    }



    /**
     * Simple implementation of an {@link OnTouchListener} for registering the dialer's touch events. 
     */
    private class MyOnTouchListener implements OnTouchListener {

        private double startAngle;

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                    // reset the touched quadrants
                    /*for (int i = 0; i < quadrantTouched.length; i++) {
                        quadrantTouched[i] = false;
                    }*/

                    //allowRotating = false;

                    startAngle = getAngle(event.getX(), event.getY());
                    break;

                case MotionEvent.ACTION_MOVE:
                    /*double rotationAngleRadians = Math.atan2(event.getX() - (dialer.getWidth() / 2 ),     ( (dialer.getHeight() / 2 ) - event.getY()));
                    double angle = (int) Math.toDegrees(rotationAngleRadians);
                    Log.i("gg", "rotaion angle"+angle);*/

                    double currentAngle = getAngle(event.getX(), event.getY());
                    //if(currentAngle < 130 || currentAngle < 110){
                        //Log.e("Start angle :"+startAngle, "Current angle:"+currentAngle);
                        rotateDialer((float) (startAngle - currentAngle));
                        startAngle = currentAngle;
                    //}


                    //Log.e("MOVE start Degree:"+startAngle, "Current Degree :"+currentAngle);
                    break;

                case MotionEvent.ACTION_UP:
                    //allowRotating = true;
                    break;
            }

            // set the touched quadrant to true
            //quadrantTouched[getQuadrant(event.getX() - (dialerWidth / 2), dialerHeight - event.getY() - (dialerHeight / 2))] = true;

            //detector.onTouchEvent(event);

            return true;
        }
    }

解决方案

Hi Girish there is a class Named RotateAnimation by using this class u can easily do it

     look Example like

      RotateAnimation r = new RotateAnimation(0f, -90f,200,200); // HERE 
      r.setStartOffset(1000);
      r.setDuration(1000);
      r.setFillAfter(true); //HERE
      animationSet.addAnimation(r);

这篇关于转动转盘有限度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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