Android中仿IOS圆盘时间选择器

public class Ring_Slide2 extends View {

private static final double RADIAN = 180 / Math.PI;

private int max_progress; // 设置最大进度

private int cur_progress; //设置锚点1当前进度

private int cur_progress2; //设置锚点2进度

private int bottom_color;//设置底色

private int circle_color; //设置圆的颜色(锚点)

private int slide_color;  //设置滑动过的颜色

private float ring_width; //圆环的宽度

private double cur_Angle;  //当前锚点1旋转角度

private double cur_Angle2; //当前锚点2的旋转角度

private float ring_Radius;//圆环的半径



private final int[] arrColorCircle = new int[]{0xFFFFde37, 0xFFFFa400};

private int main_width;  //圆的宽度

private float mWheelCurX, mWheelCurY; //圆的位置

private float mWheelCurX2, mWheelCurY2; //圆2的位置



private Paint circle_Paint; //圆环的画笔

private Paint select_Paint;//选中的画笔

private Paint dot1;   //圆点1

private Paint dot2;   //圆点2

private Context context;

private OnSeekBarChangeListener changeListener,changeListener2;

public Ring_Slide2(Context context) {

    this(context,null);

}



public Ring_Slide2(Context context, AttributeSet attrs) {

    this(context, attrs,0);

}



public Ring_Slide2(Context context, AttributeSet attrs, int defStyleAttr) {

    super(context, attrs, defStyleAttr);

    this.context=context;

    initAttrs(attrs,defStyleAttr);

    initPadding();

    //初始化画笔

    initPaints();

}



//初始化属性

private void initAttrs(AttributeSet attrs, int defStyle){

    TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.Cricle_slide, defStyle, 0);

    max_progress=typedArray.getInt(R.styleable.Cricle_slide_max_progress,720);

    cur_progress=typedArray.getInt(R.styleable.Cricle_slide_cur_progress,420);

    cur_progress2=typedArray.getInt(R.styleable.Cricle_slide_cur_progress2,540);

    if (cur_progress > max_progress) cur_progress = max_progress;

    if (cur_progress2 > max_progress) cur_progress2 = max_progress;

    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.select_sun_bg2);

    main_width= bitmap.getWidth();

    ring_width=typedArray.getFloat(R.styleable.Cricle_slide_Ring_Width,main_width);

    bottom_color=typedArray.getColor(R.styleable.Cricle_slide_bottom_color,getColor(R.color.select_main_bg_color));

    circle_color=typedArray.getColor(R.styleable.Cricle_slide_circle_color,getColor(R.color.duration));

    slide_color=typedArray.getColor(R.styleable.Cricle_slide_slide_color,getColor(R.color.time));

    typedArray.recycle();

}

//初始化边距

private void initPadding(){

    int paddingLeft = getPaddingLeft();

    int paddingTop = getPaddingTop();

    int paddingRight = getPaddingRight();

    int paddingBottom = getPaddingBottom();

    int paddingStart = 0, paddingEnd = 0;

    if (Build.VERSION.SDK_INT >= 17) {

        paddingStart = getPaddingStart();

        paddingEnd = getPaddingEnd();

    }

    int maxPadding = Math.max(paddingLeft, Math.max(paddingTop,

            Math.max(paddingRight, Math.max(paddingBottom, Math.max(paddingStart, paddingEnd)))));

    setPadding(maxPadding, maxPadding, maxPadding, maxPadding);

}

private void initPaints(){



    /*

    圆环的画笔

     */

    circle_Paint=new Paint(Paint.ANTI_ALIAS_FLAG);

    circle_Paint.setAntiAlias(true);

    circle_Paint.setColor(bottom_color);

    circle_Paint.setStyle(Paint.Style.STROKE);

    circle_Paint.setStrokeWidth(ring_width);



    /*

    选中区域的画笔

     */

    select_Paint=new Paint(Paint.ANTI_ALIAS_FLAG);

    select_Paint.setShader(new SweepGradient(0, 0, arrColorCircle, null));

    /*select_Paint.setColor(circle_color);*/

    select_Paint.setAntiAlias(true);

    select_Paint.setStyle(Paint.Style.STROKE);

    select_Paint.setStrokeWidth(ring_width);



   // 画锚点

    dot1 = new Paint(Paint.ANTI_ALIAS_FLAG);

    dot1.setColor(circle_color);

    dot1.setAntiAlias(true);

    dot1.setStyle(Paint.Style.FILL);



   // 画锚点2

    dot2 = new Paint(Paint.ANTI_ALIAS_FLAG);

    dot2.setColor(slide_color);

    dot2.setAntiAlias(true);

    dot2.setStyle(Paint.Style.FILL);



}

//获取宽度

private float getDimen(int dimenId) {

    return getResources().getDimension(dimenId);

}

//获取颜色

@TargetApi(Build.VERSION_CODES.M)

private int getColor(int colorId) {

    final int version = Build.VERSION.SDK_INT;

    if (version >= 23) {

        return getContext().getColor(colorId);

    } else {

        return ContextCompat.getColor(getContext(), colorId);

    }

}



@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.setalarm_colock_bg);

    int height = bitmap.getHeight()+main_width*2;

    int width = bitmap.getWidth()+main_width*2;

    int min = Math.min(height, width);

    setMeasuredDimension(min,min);

    initposition();

}

private void initposition(){

    //转换为360度

    cur_Angle=(double) cur_progress / max_progress*360.0;

    cur_Angle2=(double)cur_progress2 / max_progress*360.0;

    //计算初始化旋转的角度

    double cos = -Math.cos(Math.toRadians(cur_Angle));

    double cos2 = -Math.cos(Math.toRadians(cur_Angle2));

    //根据旋转的角度来确定位置

    MakeCurPosition(cos);

    MakeCurPosition2(cos2);

    //确定圆环的半径

    ring_Radius=(getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - ring_width) / 2;

}

private void MakeCurPosition(double cos){

    //根据旋转的角度来确定圆的位置

    //确定x点的坐标

    mWheelCurX = calcXLocationInWheel(cur_Angle, cos);

    //确定y点的坐标

    mWheelCurY=calcYLocationInWheel(cos);

}

private void MakeCurPosition2(double cos2){

    //根据旋转的角度来确定圆的位置

    //确定x点的坐标

    mWheelCurX2 = calcXLocationInWheel(cur_Angle2, cos2);

    //确定y点的坐标

    mWheelCurY2=calcYLocationInWheel(cos2);

}

//确定x点的坐标

private float calcXLocationInWheel(double angle,double cos){

    if (angle < 180) {

        return (float) (getMeasuredWidth() / 2 + Math.sqrt(1 - cos * cos) * ring_Radius); //Math.sqrt正平分根  9-3

    } else {

        return (float) (getMeasuredWidth() / 2 - Math.sqrt(1 - cos * cos) * ring_Radius);

    }

}



//确定y点的坐标

private float calcYLocationInWheel(double cos) {

    return getMeasuredWidth() / 2 + ring_Radius * (float) cos;

}



@Override

protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    float left = getPaddingLeft() + ring_width / 2;

    float top = getPaddingTop() + ring_width / 2;

    float right = canvas.getWidth() - getPaddingRight() - ring_width / 2;

    float bottom = canvas.getHeight() - getPaddingBottom() - ring_width / 2;

    float centerX = (left + right) / 2;

    float centerY = (top + bottom) / 2;



    float wheelRadius = (canvas.getWidth() - getPaddingLeft() - getPaddingRight()) / 2 - ring_width / 2;

    canvas.drawCircle(centerX, centerY, wheelRadius, circle_Paint);

    //画选中区域

  //  canvas.drawArc(new RectF(left, top, right, bottom), (float) (Math.PI * RADIAN + Math.acos(cur_Angle) * RADIAN), (float) (Math.abs(cur_Angle-cur_Angle2)), false, select_Paint);

    Log.i("TAG","第一个的角度="+cur_Angle);

    Log.i("TAG","第一个的角度2="+cur_Angle2);

    float begin=0; //圆弧的起点位置

    float stop=0;

    if(cur_Angle>180  && cur_Angle>cur_Angle2 ){   //180  -- 360

        begin=(float) (-Math.abs(cur_Angle-360)-90);

        stop=(float) Math.abs(Math.abs(cur_Angle-360)+cur_Angle2);

        Log.i("TAG","begin="+begin);

        Log.i("TAG","stop="+stop);

    }else if(cur_Angle>cur_Angle2){

        begin=(float) cur_Angle-90;

        stop=(float)(360-(cur_Angle-cur_Angle2));

    }else {

         begin=(float) cur_Angle-90;

        stop=(float) Math.abs(cur_Angle-cur_Angle2);

    }

    canvas.drawArc(new RectF(left, top, right, bottom), begin,stop, false, select_Paint);



    //画锚点   画圆

    canvas.drawCircle(mWheelCurX, mWheelCurY, ring_width/2, dot1);

    //画锚点   画圆

    canvas.drawCircle(mWheelCurX2, mWheelCurY2, ring_width/2, dot2);



    Log.i("TAG","锚点1Y"+mWheelCurY+"锚点1X"+mWheelCurX);

    Log.i("TAG","锚点2Y"+mWheelCurY2+"锚点1X"+mWheelCurX2);



}



@Override

public boolean onTouchEvent(MotionEvent event) {

    float x = event.getX();

    float y = event.getY();

    int flag=0;

    //判断是否触控到两个点中的其中某个点



    if(isMovedot2(x,y)){

        flag=2;

    }else if(isMovedot1(x,y)){

        flag=1;

    }

   /* if(isMovedot1(x,y)){

        flag=1;

    }else if(isMovedot2(x,y)){

        flag=2;

    }*/

    if(event.getAction()==MotionEvent.ACTION_MOVE || isMovedot1(x,y) ==true || isMovedot2(x,y)==true ){

        Log.i("TAG","进入X="+x+"进入Y="+y);

        //通过触摸点算出cos角度值

        float cos = calculateCos(x, y);

        // 通过反三角函数获得角度值

        double angle;   //获取滑动的角度

        if (x < getWidth() / 2) { // 滑动超过180度

            angle = Math.PI * RADIAN + Math.acos(cos) * RADIAN;    //通过计算得到滑动的角度值

        } else { // 没有超过180度

            angle = Math.PI * RADIAN - Math.acos(cos) * RADIAN; //PI 周长比直径    返回弧角度的余弦值

        }

        if(flag==1){

            cur_Angle=angle;

            cur_progress=getSelectedValue(cur_Angle);

            MakeCurPosition(cos);

            if (changeListener != null) {

                changeListener.onChanged(this, cur_progress);

            }

        }else if(flag==2){

            cur_Angle2=angle;

            cur_progress2=getSelectedValue(cur_Angle2);

            MakeCurPosition2(cos);

            if (changeListener2 != null) {

                changeListener2.onChanged(this, cur_progress2);

            }

        }

        invalidate();

        return true;

    }else {

        return super.onTouchEvent(event);

    }

}



private  boolean isMovedot1(float x,float y){

    float dot1x = Math.abs(mWheelCurX - x);

    float dot1y = Math.abs(mWheelCurY - y);

    if(dot1x<30 && dot1y<30){

        return true;

    }else{

        return false;

    }

}

private boolean isMovedot2(float x,float y){

    float dot1x = Math.abs(mWheelCurX2 - x);

    float dot1y = Math.abs(mWheelCurY2 - y);

    if(dot1x<30 && dot1y<30){

        return true;

    }else{

        return false;

    }

}



//拿到切斜角的cos值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值