Android自定义View圆盘滑动控件(已适配多种分辨率)
2016-04-25 20:51
477 查看
好久没写博客了,最近在写一个项目时需要一个可以调节档位的圆盘, 首先实现这个圆盘自定义View,首先在构造方法中定义画笔,重写onDraw(Canvas canvas)方法,进行绘制,首先绘制一个大圆,然后我这个大圆周围的表盘显示一共有9个档位,为了美观,每个档位里面有8个小指针,这样一个分为72份,也就是没5°画一次,由于我这个还需要有一个设定档位的按钮,所以添加档位的档位设置。
下面说一下滑动手势的处理
我们可以在oNMeasure()方法得到该控件的大小,除以2就是圆心,我们设定的大圆的半径为200,用圆心y坐标减去200就是0档位的y坐标,通过获取当前手势位置,就可以通过这三个点构建三角形,通过初中学的余弦定理可以求得滑动角度,当滑动到左半部分,角度注意要用360-当前角度。
屏幕适配看了hongyang大神Orz的适配方案,/article/1580259.html
————————–分割线————————————-
上代码
效果图
下面说一下滑动手势的处理
我们可以在oNMeasure()方法得到该控件的大小,除以2就是圆心,我们设定的大圆的半径为200,用圆心y坐标减去200就是0档位的y坐标,通过获取当前手势位置,就可以通过这三个点构建三角形,通过初中学的余弦定理可以求得滑动角度,当滑动到左半部分,角度注意要用360-当前角度。
屏幕适配看了hongyang大神Orz的适配方案,/article/1580259.html
————————–分割线————————————-
上代码
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基础知识: Android基本认识和入门案例
- Android开发踩过的坑(一)
- Android调用WebService详解
- Android 真机投影工具 Vysor 使用教程
- Android RelativeLayout动态修改子控件位置(可连续拖动的View)
- Android 系统相册不可见问题
- Android中保存图片到U盘提示Permission denied
- Android中View的事件分发机制
- Android Studio中关联源码(source for Android API)的方法
- android自定义View之NotePad出鞘记
- android自定义View之NotePad出鞘记
- android自定义View之NotePad出鞘记
- (4.6.11)从Android源码到apk——apk打包过程
- android自定义View之NotePad出鞘记
- CharmingAndroid框架类整理之VPIndicator类——ViewPager的指示器
- 诡异的Android开发中EditText键盘弹出后被遮盖的bug
- Android 状态栏的动态显示和隐藏
- (4.2.26)一个特别适合新手练习的Android小项目——每日一妹纸
- Aandroid 标题显示进度条遇到的问题总结
- Android学习——四大组件之Service