自定义view-绘图时钟
来源:互联网 发布:怎么做淘宝联盟分享赚 编辑:程序博客网 时间:2024/05/28 16:14
首先看下效果图,速度被我调快了,秒针转完一圈,分针跳动一格,分针转完一圈,时针跳动一格,完美模拟时钟的效果。
要实现如上自定义view,首先继承view,并重写构造方法:
/** * Created by yanjiang on 2015/12/14. */public class ClockView extends View { public ClockView(Context context) { super(context); init(); } public ClockView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ClockView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); }init()方法是为了初始化一些操作,写一些只执行一次的操作
private void init() { p1 = new Paint(); p2 = new Paint(); p3 = new Paint(); p4 = new Paint(); pFen=new Paint(); pShi=new Paint(); p1.setColor(Color.RED); p1.setStrokeWidth(4); p1.setStyle(Paint.Style.STROKE); p1.setAntiAlias(true); p2.setColor(Color.RED); p2.setTextSize(50); p2.setStyle(Paint.Style.FILL); p3.setStyle(Paint.Style.FILL); p3.setColor(Color.GREEN); p3.setStrokeWidth(2); p3.setAntiAlias(true); p4.setColor(getResources().getColor(R.color.sr_color_primary_dark)); pFen.setColor(Color.GRAY); pFen.setAntiAlias(true); pFen.setStrokeWidth(8); pShi.setColor(getResources().getColor(R.color.black)); pShi.setAntiAlias(true); pShi.setStrokeWidth(15); WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(dm); width = dm.widthPixels; height = dm.heightPixels;/*初始化分针位置*/ xFen=width/2; yFen=height/2-width/4;/*初始化时针位置*/ xShi=width/2+width/5; yShi=height/2; new MyThread().start(); }定义画笔以及配置一些参数,和初始化信息。接下来重写onDraw方法,核心绘图部分:
@Override protected void onDraw(Canvas canvas) { Path path = new Path(); RectF rect1 = new RectF(width / 6, (height - width * 2 / 3) / 2, width - (width / 6), height - (height - width * 2 / 3) / 2); path.addArc(rect1, 225, 315); int count = 60; //总刻度数 for (int i = 0; i < count; i++) { if (i % 5 == 0) { canvas.drawLine(width / 2, height / 2, width / 2, height / 2 + width / 3 + 30, p1); String num = String.valueOf(i / 5 + 0); if (num.equals("0")) { num = "12"; } canvas.drawText(num, width / 2 - 15, height / 2 - width / 3 - 50, p2); } else { canvas.drawLine(width / 2, height / 2, width / 2, height / 2 + width / 3 + 15, p3); } canvas.rotate(360 / count, width / 2, height / 2); //旋转画纸 } canvas.drawCircle(width / 2, height / 2, width / 3, p4); canvas.drawCircle(width / 2, height / 2, width / 3, p1); canvas.drawCircle(width / 2, height / 2, 20, p3); canvas.drawTextOnPath("全绘图时钟,你值得拥有", path, 0, 60, p2); canvas.save(); //时针 canvas.drawLine(width / 2, height / 2, xShi, yShi, pShi);//分针 canvas.drawLine(width / 2, height / 2, xFen, yFen, pFen);//秒针 canvas.drawLine(width / 2, height / 2, x, y, p1); canvas.drawCircle(width / 2, height / 2, 10, p2); // canvas.drawLine(width / 2, height / 2, (float) (width/2+(width/3)*Math.cos(30 * Math.PI / 180)), (float) (height/2-(width / 3 * Math.sin(30* Math.PI / 180))), p1); // canvas.drawLine(width / 2, height / 2 + 35, width / 2 + x, (height - 2 * width / 3) / 2 + 10 + y, p1); // canvas.rotate(angel, width / 2, height / 2); // canvas.restore();//duration执行完成后重复执行 }将动态变化的地方用变量表示,然后开启线程进行变量值的修改,最后重绘:
public class MyThread extends Thread { @Override public void run() { while (true) { float j, k,jFen,kFen,jShi,kShi; j = (float) Math.cos(sweepAngle * Math.PI / 180); k = (float) Math.sin(sweepAngle * Math.PI / 180); x = width / 2 + j * (width / 3); y = height / 2 + k * (width / 3); sweepAngle += 6; if(sweepAngle==270){ sweepAngle=-90; sweepAngleFen+=6; jFen = (float) Math.cos(sweepAngleFen * Math.PI / 180); kFen = (float) Math.sin(sweepAngleFen * Math.PI / 180); xFen = width / 2 + jFen * (width / 4); yFen = height / 2 + kFen * (width / 4); if(sweepAngleFen==270){ sweepAngleFen=-90; sweepAngleShi+=6; jShi = (float) Math.cos(sweepAngleShi * Math.PI / 180); kShi = (float) Math.sin(sweepAngleShi * Math.PI / 180); xShi = width / 2 + jShi * (width / 5); yShi = height / 2 + kShi * (width / 5); } } postInvalidate(); SystemClock.sleep(10); } }}
以上即可实现如图功能,将sleep改为1000即可,最后加上手势波动秒针跟随手指旋转功能:
@Overridepublic boolean onTouchEvent(MotionEvent event) { float j, k; if (event.getAction() == MotionEvent.ACTION_MOVE) { x = event.getX(); y = event.getY(); j = (float) ((y - height / 2) / Math.sqrt((x - width / 2) * (x - width / 2) + (y - height / 2) * (y - height / 2))); k = (float) ((x - width / 2) / Math.sqrt((x - width / 2) * (x - width / 2) + (y - height / 2) * (y - height / 2))); y = (width / 3) * j + height / 2; x = (width / 3) * k + width / 2; if (y > height / 2) sweepAngle = Math.acos(k) * 180 / Math.PI; else sweepAngle = 2* Math.PI- Math.acos(k) * 180 / Math.PI; Log.e("yan", sweepAngle + ""); invalidate(); } return true;}效果如下 :
2 0
- 自定义view-绘图时钟
- 自定义view绘制时钟
- <3> 自定义view 时钟
- 自定义View绘制时钟
- 自定义View,绘图
- Android绘图:自定义View之——矩形进度条、圆环进度条、填充型进度条、时钟
- 自定义View实现米老鼠时钟
- 初尝试自定义view-时钟
- android 自定义view实现时钟
- 自定义View之手绘时钟
- Android 自定义View 时钟效果
- Android自定义View---秒表/时钟
- Android自定义View时钟效果
- 自定义View-酷炫时钟
- android 自定义View模拟时钟
- Android自定义View绘图基础
- 自定义绘图View之onDraw
- android自定义view之自定义时钟wacthview
- MySql查询时间段的方法
- OperationDemo2
- 值得推荐的C/C++框架和库 (真的很强大)
- 位运算符
- centos 中使用 Docker 搭建 Java Web 运行环境
- 自定义view-绘图时钟
- Deep Learning 读书笔记(一)
- js的常用函数,自定义对象,内置对象
- 数据挖掘算法之离散化和二元化
- 生活中的心理学
- object-c 基础动画的学习总结
- AssignVar
- TCP/IP(1)-基本概念
- xcode下出现Undefined symbols for architecture arm64或者armv7: “_OBJC_CLASS_$_XXX