[置顶] Android自定义View圆盘滑动控件(已适配多种分辨率)

好久没写博客了,最近在写一个项目时需要一个可以调节档位的圆盘, 首先实现这个圆盘自定义View,首先在构造方法中定义画笔,重写onDraw(Canvas canvas)方法,进行绘制,首先绘制一个大圆,然后我这个大圆周围的表盘显示一共有9个档位,为了美观,每个档位里面有8个小指针,这样一个分为72份,也就是没5°画一次,由于我这个还需要有一个设定档位的按钮,所以添加档位的档位设置。
下面说一下滑动手势的处理
我们可以在oNMeasure()方法得到该控件的大小,除以2就是圆心,我们设定的大圆的半径为200,用圆心y坐标减去200就是0档位的y坐标,通过获取当前手势位置,就可以通过这三个点构建三角形,通过初中学的余弦定理可以求得滑动角度,当滑动到左半部分,角度注意要用360-当前角度。
屏幕适配看了hongyang大神Orz的适配方案,http://blog.csdn.net/lmj623565791/article/details/45460089

————————–分割线————————————-
上代码

package com.example.yasin.dianretan.utils;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.example.yasin.dianretan.R;

import java.util.Calendar;

/** * Created by Yasin on 2016/4/7. */
public class CirclerView extends View {

    private int width;
    private int height;
    private Paint mPaintLine;
    private Paint mPaintCircle;
    private Paint mPaintSec;
    private Paint mPaintText,mPaintText2;
    private int dw;//当前档位
    public static final int NEED_INVALIDATE = 0X23;
    private double cx,cy;//手势坐标
    private double yxx,yxy;//圆心
    private String name;
    private double jd;//滑动的角度

    //每隔一秒,在handler中调用一次重新绘制方法
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what){
                case NEED_INVALIDATE:
                    invalidate();//告诉UI主线程重新绘制
                    handler.sendEmptyMessageDelayed(NEED_INVALIDATE,1000);
                    break;
                default:
                    break;
            }
        }
    };

    public CirclerView(Context context) {
        super(context);
    }

    public CirclerView(Context context, AttributeSet attrs) {
        super(context, attrs);

        /* * 定义多个画不同东西的画笔 * */
        mPaintLine = new Paint();
        mPaintLine.setColor(Color.WHITE);
        mPaintLine.setStrokeWidth(6);

        mPaintCircle = new Paint();
        mPaintCircle.setColor(context.getResources().getColor(R.color.yellow));//设置颜色
        mPaintCircle.setStrokeWidth(10);//设置线宽
        mPaintCircle.setAntiAlias(true);//设置是否抗锯齿
        mPaintCircle.setStyle(Paint.Style.STROKE);//设置绘制风格


        mPaintText = new Paint();
        mPaintText.setColor(Color.WHITE);
        mPaintText.setStrokeWidth(10);
        mPaintText.setTextAlign(Paint.Align.CENTER);
        mPaintText.setTextSize(40);

        mPaintText2 = new Paint();
        mPaintText2.setColor(Color.WHITE);
        mPaintText2.setStrokeWidth(10);
        mPaintText2.setTextAlign(Paint.Align.CENTER);
        mPaintText2.setTextSize(60);

        //滑针
        mPaintSec = new Paint();
        mPaintSec.setStrokeWidth(10);
        mPaintSec.setColor(Color.YELLOW);


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        yxx = width/2;
        yxy = height/2;
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int circleRadius = 200;//大圆半径
        //画出大圆
        canvas.drawCircle(width / 2, height / 2, circleRadius, mPaintCircle);

        //依次旋转画布,画出每个刻度和对应数字
        if(dw==0){
            mPaintText2.setColor(Color.RED);
            canvas.drawText("关",width/2,height/2+60,mPaintText2);
        }else{
            mPaintText2.setColor(Color.WHITE);
            canvas.drawText(dw+"档",width/2,height/2+60,mPaintText2);
        }

        mPaintText2.setColor(Color.YELLOW);
        mPaintText2.setTextSize(40);
        canvas.drawText(name, width / 2, height / 2 - 50, mPaintText2);

        for (int i = 0; i <= 71; i++) {//一共有72个(刻度+档位文字)
            canvas.save();//保存当前画布
            canvas.rotate(360 / 72 * i, width / 2, height / 2);
           // canvas.rotate((float)jd, width / 2, height / 2);
            if(i%8!=0) {
                if(i<dw*8||i<jd/5.0f){/*如果使用的档位调节,则该档位内的都有黄色; 如果滑动的,一个刻度是5°,s所以个当前度数除以5*/
                    mPaintLine.setColor(Color.YELLOW);
                }else{
                    mPaintLine.setColor(Color.WHITE);
                }
                canvas.drawLine(width / 2, height / 2 - circleRadius-10, width / 2, height / 2 - circleRadius - 30, mPaintLine);
            }else {
                //左起:文本内容,起始位置x坐标,起始位置y坐标,画笔
                if(i/8<=dw){
                    mPaintText.setColor(Color.YELLOW);
                }else{
                    mPaintText.setColor(Color.WHITE);
                }
                canvas.drawText("" + i / 8, width / 2, height / 2 - circleRadius - 20, mPaintText);
            }
            canvas.restore();
        }

        float secDegree = (float) jd;//dw/9f*360;//得到指针旋转的角度
        canvas.save();
        canvas.rotate(secDegree, width / 2, height / 2);
        canvas.drawLine(width / 2, height / 2 - circleRadius, width / 2, height / 2 - circleRadius - 30, mPaintSec);

        canvas.restore();

    }

    public void setDw(int dw){
        this.dw = dw;
        //handler.sendEmptyMessage(NEED_INVALIDATE);//向handler发送一个消息,让它开启重绘
        this.jd = dw*40;
        invalidate();
    }
    public int getDw(){
        return dw;
    }

    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        cx=event.getX();
        cy=event.getY();

        jd = getJD(cx,cy);
        if(cx<=yxx) {
            jd=180+(180-jd);
        }
        dw = (int) (jd/40);
        invalidate();
        return true;
    }

    /* * type 1表示得到距离,2表示得到的距离的平方 * */
    private double getJL(double ax,double ay,double bx,double by,int type){
        if(type==1){
            return Math.sqrt(((ax-bx)*(ax-bx)+(ay-by)*(ay-by)));
        }else{
            return (((ax-bx)*(ax-bx)+(ay-by)*(ay-by)));
        }
    }
//计算角度
    private double getJD(double ax,double ay){
        return (Math.acos(((getJL(ax,ay,yxx,yxy,2)+200*200-getJL(ax,ay,yxx,(yxy-200),2))/(2*200*getJL(ax,ay,yxx,yxy,1))))*180/Math.PI);
    }

}

效果图
[置顶] Android自定义View圆盘滑动控件(已适配多种分辨率)_第1张图片

你可能感兴趣的:(自定义控件及其屏幕适)