一个半圆形拖动条

请标注原文链接地址:https://blog.csdn.net/daxiangzaici/article/details/50470134

pulic class Rota_CircleView extends View {

    private Paint paint;
    private float a=330f,b=330f;
    private float cx=370f,cy=470f;
    private float track_radius = 100f;  //圆弧半径
    private int width;
    private double mAngleDeg=0; //角度 相对  startAngle 的    角度 
    private Bitmap mThumbBitmap;
     
    private double mAngleRad = 1;  //当前角度对应的弧度
    private double startAngleDeg=30f;  //起点与水平方向的夹角
    private double totalAngleDeg = 180; 
    private boolean mEnable = true;
    
    private float mPercent = 0;  //百分比
    public interface OnCircleViewChangeListener {//圆弧拖动时候回调接口,包括拖动弧度所占百分比,停止拖动时候所占百分比
        void onStopTouch(float percent);
        void onMoveTouch(float percent);

    }

private OnCircleViewChangeListener mOnCircleViewChangeListener;
    
    public void setOnCircleViewChangeListener(OnCircleViewChangeListener l) {
        mOnCircleViewChangeListener = l;
    }
    
    public Rota_CircleView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub 
    }


    public Rota_CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
        getAttrs(context, attrs);
    }
    
    public Rota_CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        getAttrs(context, attrs);        
    }
    
     
    /**
     * 得到属性值
     * 
     * @param context
     * @param attrs
     */
    private void getAttrs(Context context, AttributeSet attrs) { 
        
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Rota_CircleView);
        track_radius = ta.getDimension(R.styleable.Rota_CircleView_track_radius, 100f);       
        int bmp_id = ta.getResourceId(R.styleable.Rota_CircleView_dot_bmp, R.drawable.scrubber_control_normal_holo);
        ta.recycle();
        
        mThumbBitmap = BitmapFactory.decodeResource(getResources(), bmp_id);
        totalAngleDeg = 180 + 2 * startAngleDeg;
        
        DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
        Log.i("tzc","track_radius = " + track_radius+", dm.densityDpi = " + dm.densityDpi);
    }

 @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        getParent().requestDisallowInterceptTouchEvent(true);  
        return super.dispatchTouchEvent(event);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!mEnable) 
            return false;
        
        // TODO Auto-generated method stub
        switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float newx=event.getX();
            float newy=event.getY();
            
            pointxy xy = touchToPoint(newx, newy);
            cx = xy.x;
            cy = xy.y;
            if(mOnCircleViewChangeListener != null) {
                mOnCircleViewChangeListener.onMoveTouch(mPercent);
            }

     invalidate();   
            break;
            
        case MotionEvent.ACTION_UP:
            if(mOnCircleViewChangeListener != null) {
                mOnCircleViewChangeListener.onStopTouch(mPercent);
            }
            break;
        default:
            break;
        }
        return true;
    }
    
    /*
     *  由触摸点坐标 获得 相对 startAngle 的角度
     */
    private double pointToAngle(float newx, float newy) {
        double angle = 0;    //角度 相对  startAngle 的    角度 
        double degrees = 0;  //角度

        float y = b - newy;
        if (x > 0 && y > 0) {
            x = newx - a;
            y = b - newy;
            mAngleRad = Math.atan(x / y);
            degrees = mAngleRad*180/Math.PI;
            angle = startAngleDeg + 90 + degrees;           
        } else if (x > 0 && y < 0) {
            x = newx - a;
            y = newy - b;
            mAngleRad = Math.atan(x / y);
            degrees = mAngleRad*180/Math.PI;
            angle = startAngleDeg + 270 - degrees;          
        } else if (x < 0 && y < 0) {
            x = a - newx;
            y = newy - b;
            mAngleRad = Math.atan(x / y);
            degrees = mAngleRad*180/Math.PI;
            angle = startAngleDeg - 90 + degrees;            
        } else if (x < 0 && y > 0) {
            x = a - newx;
            y = b - newy;

     mAngleRad = Math.atan(x / y);
            degrees = mAngleRad*180/Math.PI;       
            angle = startAngleDeg + 90 - degrees;     
        }       
        return angle;
    }
    
    
    private pointxy touchToPoint(float newx, float newy) {
        pointxy xy = new pointxy(0, 0);
        mAngleDeg = pointToAngle(newx, newy); 
        mPercent = (float) (mAngleDeg/totalAngleDeg);
        Log.i("tzc", "angle1 = " + mAngleDeg );
        if(mAngleDeg <=0.0) 
            mAngleDeg = 360 + mAngleDeg;
        
        if(mAngleDeg >= totalAngleDeg)
            mAngleDeg = totalAngleDeg;

 Log.i("tzc", "angle2 = " + mAngleDeg );
        double x_sin = track_radius * Math.sin(mAngleRad);
        double y_cos = track_radius * Math.cos(mAngleRad);
        Log.i("tzc", "x_sin = " + x_sin + "y_cos = " + y_cos );
        
        
        float x = newx - a;
        float y = b - newy;  
        double x_2 = x_sin;
        double y_2 = y_cos;
        
        if (x > 0 && y > 0) {            
        
        } else if (x > 0 && y < 0) { 
            y_2 = -1*y_2;     
        } else if (x < 0 && y < 0) {      
            x_2 = -1*x_2;
            y_2 = -1*y_2;       
        } else if (x < 0 && y > 0) {        
            x_2 = -1*x_2;            
        }  

  if( isLimit(x_2, y_2)) {
            Log.i("tzc", "isLimit");
            if(x_2 < 0) {
                xy = angleToPoint(0);
            } else {
                xy = angleToPoint(totalAngleDeg);
            }
        } else {
        
            if (x > 0 && y > 0) {            
                xy.x = (float) (a + x_sin);
                xy.y = (float) (b - y_cos);
            } else if (x > 0 && y < 0) {     
                xy.x = (float) (a + x_sin);
                xy.y = (float) (b + y_cos);      
            } else if (x < 0 && y < 0) {      
                xy.x = (float) (a - x_sin);
                xy.y = (float) (b + y_cos);      
            } else if (x < 0 && y > 0) {        
                xy.x = (float) (a - x_sin);
                xy.y = (float) (b - y_cos);
            } 
        }

    return xy;
    }
    
    private class pointxy{
        public float x;
        public float y;
        pointxy(float x, float y){
            this.x = x;
            this.y = y;
        }
    }
    
    private boolean isLimit (double x_sin, double y_cos) {
        boolean limit = false;
        
        if(y_cos < 0) {
            if(x_sin == 0) {
                limit = true;
            }  else if(x_sin < 0){
                if(x_sin > y_cos) {
                    limit = true; 

               }
            }  else {
                if(x_sin < -1*y_cos) {
                    limit = true; 
                }
            }                
        }
        
        return limit;
    }
    
    
    public void setEnable(boolean enble) {
        this.mEnable = enble;
    }
     private pointxy angleToPoint(double angle) {
        pointxy xy = new pointxy(0, 0);
        
        double angdeg1 = angle - startAngleDeg;
        double angdeg = Math.abs(angdeg1); 
     
        double radians = Math.toRadians(angdeg);
        float x = (float) (track_radius * Math.cos(radians));
        float y = (float) (track_radius * Math.sin(radians));
   
        if (angdeg1 <= 0f) {
            xy.x = (float) (a - x);
            xy.y = (float) (b + y); 
        } else {
            xy.x = (float) (a - x);
            xy.y = (float) (b - y);
        } 
        return xy;        
    }

 public void setThumbPos(float Percent) {
        pointxy xy = new pointxy(0, 0);
        mAngleDeg = totalAngleDeg * Percent;   
        xy = angleToPoint(mAngleDeg);        
        cx = xy.x;
        cy = xy.y; 
        mPercent = Percent;
        if(mOnCircleViewChangeListener != null) {
            mOnCircleViewChangeListener.onMoveTouch(mPercent);
        }
        invalidate();
    }

 public void setThumbPos(float Percent) {
        pointxy xy = new pointxy(0, 0);
        mAngleDeg = totalAngleDeg * Percent;   
        xy = angleToPoint(mAngleDeg);        
        cx = xy.x;
        cy = xy.y; 
        mPercent = Percent;
        if(mOnCircleViewChangeListener != null) {
            mOnCircleViewChangeListener.onMoveTouch(mPercent);
        }
        invalidate();
    }

 @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        //Log.i("tzc", "onDraw()");
        if(mThumbBitmap != null) {
            int h = mThumbBitmap.getHeight();
            int w = mThumbBitmap.getWidth();
            canvas.drawBitmap(mThumbBitmap, cx-w/2, cy-h/2, null);             
        }       
      
        paint = new Paint();        
        RectF rectF=new RectF(15,10,width-15,width-10);
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth(22);
        paint.setAntiAlias(true);

  SweepGradient shader=new SweepGradient(cx, cy, new int[]{0xFFE64506,0xFF1D2BF2,0xFF1D2BF0,Color.GREEN,Color.YELLOW,0xFFE64506,0xFFE64506},
                new float[]{0,0.3f,0.5f,0.7f,0.8f,0.9f,1});
        paint.setShader(shader);
        canvas.drawArc(rectF, 150,(float)mAngleDeg,false, paint);    
    }
    public void set_value(int value){
        
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub

 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);  
        a = width/2;
        b = width/2; 
        //Log.i("tzc", "onMeasure()");
        //cx=(float) (a-track_radius*Math.sin(radians));
        //cy=(float) (b+track_radius*Math.cos(radians));
        //invalidate();
    }
    


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值