这里是自定义view(二),上一篇关于自定义view的一些基本知识,比如说自定义view的步骤、会涉及到哪些函数以及如何实现自定义属性,同时实现了一个很基础的自定义控件,一个自定义的计时器,需要看的人可以点击这个链接:http://www.cnblogs.com/YaoJianXun/p/5806926.html。

  这次讲的是如何通过坐标系的变化实现一些更复杂的自定义view绘制,上一次博客我们实现了一个类似于计时器的环形控件,这次我们在那个基础上再做一次改动,通过坐标系的变动实现下面的效果:

  这里想讲一下关于android坐标系的一些东西:

1、android 坐标系

  在android中有两种常用坐标系:

1.1 android坐标系

  android坐标系就是以屏幕左上方为原点,向右为x轴正方向,向下为y轴正方的坐标系,可以使用getLocationOnScreen(intlocation[])这个函数获取Android坐标系中点的位置,可就是视图左上角在android坐标系中的位置。

1.2 视图坐标系

  这个坐标系描述的是子视图在父视图中的位置,就是子视图左上角在父视图总的位置,坐标系的原点在父视图的左上角,向右为x轴正方向,向下为y轴正方向。

1.3 坐标系常用函数

  • view的方法:

  getTop():获取到的是view自身顶边到期父布局顶边的距离。

getLeft():获取到的是view自身的左边到其父布局左边的距离。

getBottom(),getRight()也同上,获取的分别是view自身下边右边到其父布局下边右边的距离。

  • MotionEvent的方法:

  getX():获取点击事件距离控件左边的距离,视图坐标。

getY():获取点击事件距离控件上边的距离,视图坐标。

getRawX(),getRawY(),同上,只是他们获取的android坐标系中的距离,绝对坐标。

1.4 通过坐标系移动实现view绘制

  这里介绍两个函数:

  • translate():平移android坐标系
  • rotate():旋转android坐标系

  分析上面图中的效果如何实现:

  • 外围的圆形

  这个就不做讲述了,很容易实现的效果。

  • 表盘上的刻度

  这个就要分析一下了,首先画出12点的刻度很容,由于它是一条竖直的直线,只需要指定起止点就可以直接绘制出来了。那么其他的刻度呢,起止点就没有那么容易计算得到了,那么怎么办呢,这个时候其实只要将android坐标系以原点为中心旋转一定的角度,在绘制和12点方向一样的线,就可以了,只不过刻度不同,可能线的长度不同,这个需要设置条件语句进行具体判断,但是绘制的方向很容易就得出来了。下面是代码:

      for (int i = 0; i < 60; i++) {//通过旋转坐标系绘制刻度String degree = String.valueOf(i / 5);if (i % 15 == 0) {mPaint2.setStrokeWidth(5);mPaint2.setTextSize(30);canvas.drawLine(mCircleXY, 20, mCircleXY, 80, mPaint2);if (i == 0) {canvas.drawText("12", mCircleXY - mPaint2.measureText(degree) / 2, 120, mPaint2);} else {canvas.drawText(degree, mCircleXY - mPaint2.measureText(degree) / 2, 120, mPaint2);}} else if (i % 5 == 0) {mPaint2.setStrokeWidth(5);mPaint2.setTextSize(30);canvas.drawLine(mCircleXY, 20, mCircleXY,60, mPaint2);canvas.drawText(degree, mCircleXY - mPaint2.measureText(degree) / 2, 100, mPaint2);} else {mPaint2.setStrokeWidth(5);mPaint2.setTextSize(30);canvas.drawLine(mCircleXY, 20, mCircleXY, 40, mPaint2);}canvas.rotate(6, mCircleXY, mCircleXY);}

  通过上面的代码也能看出,每次选择6度一共旋转60次,每次绘制线的时候判断一下,如果现在整点数,绘制的线长度长一点,如果是12点、3点、6点、9点绘制的线的长度要更长一点。

  • 绘制时针分针

  这个就更简单了,通过translate()函数移动android坐标系原点到表盘中间,在从中间画出两条长短不一的线就可以了。同时没过一秒,选择一定角度就可以了。下面是代码:

     //平移坐标系,绘制时针canvas.translate(mCircleXY, mCircleXY);canvas.drawLine(0, 0, 100, 100, mPaint3);//旋转坐标系,绘制分针canvas.rotate(6 * time, 0, 0);canvas.drawLine(0, 0, 100, 200, mPaint4);time++;postInvalidateDelayed(1000);

  下面是完整的全部代码:

public class CustomView extends View {private float mCircleXY, mLength, mRadius;private Paint mPaint1 = new Paint();   //表圆弧private Paint mPaint2 = new Paint();   //表刻度private Paint mPaint3 = new Paint();   //表时针private Paint mPaint4 = new Paint();   //表秒针private WindowManager mWM;private int time = 0;private int hour = 0;public CustomView(Context context) {super(context);mPaint1.setStyle(Paint.Style.STROKE);mPaint1.setStrokeWidth(5);mPaint1.setAntiAlias(false);mPaint3.setStrokeWidth(20);mPaint4.setStrokeWidth(10);setValues();}public CustomView(Context context, AttributeSet attrs) {super(context, attrs);mPaint1.setStyle(Paint.Style.STROKE);mPaint1.setStrokeWidth(5);mPaint1.setAntiAlias(false);mPaint3.setStrokeWidth(20);mPaint4.setStrokeWidth(10);setValues();}private void setValues() {mWM = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);mLength = mWM.getDefaultDisplay().getWidth();mCircleXY = mLength / 2;mRadius = (float) (mLength * 0.5);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制钟表外圈圆环canvas.drawCircle(mCircleXY, mCircleXY, mRadius-20, mPaint1);//消除锯齿canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG));for (int i = 0; i < 60; i++) {//通过旋转坐标系绘制刻度String degree = String.valueOf(i / 5);if (i % 15 == 0) {mPaint2.setStrokeWidth(5);mPaint2.setTextSize(30);canvas.drawLine(mCircleXY, 20, mCircleXY, 80, mPaint2);if (i == 0) {canvas.drawText("12", mCircleXY - mPaint2.measureText(degree) / 2, 120, mPaint2);} else {canvas.drawText(degree, mCircleXY - mPaint2.measureText(degree) / 2, 120, mPaint2);}} else if (i % 5 == 0) {mPaint2.setStrokeWidth(5);mPaint2.setTextSize(30);canvas.drawLine(mCircleXY, 20, mCircleXY,60, mPaint2);canvas.drawText(degree, mCircleXY - mPaint2.measureText(degree) / 2, 100, mPaint2);} else {mPaint2.setStrokeWidth(5);mPaint2.setTextSize(30);canvas.drawLine(mCircleXY, 20, mCircleXY, 40, mPaint2);}canvas.rotate(6, mCircleXY, mCircleXY);}//平移坐标系,绘制时针canvas.translate(mCircleXY, mCircleXY);canvas.drawLine(0, 0, 100, 100, mPaint3);//旋转坐标系,绘制分针canvas.rotate(6 * time, 0, 0);canvas.drawLine(0, 0, 100, 200, mPaint4);time++;postInvalidateDelayed(1000);}}

  这样就可以绘制出图中所示的表盘,源码的链接:https://github.com/jiushi555/CustomView/tree/master/CustomTimepiece。

  转载请标明出处。


不是闷骚的程序员算不上程序员。我的微信公众号“那点鼻事”,在这里周一到周五每天一篇文章,与技术无关,只哈牛逼。

转载于:https://www.cnblogs.com/YaoJianXun/p/5832939.html

自定义view(二)相关推荐

  1. android下雨动画效果,Android 自定义View(二) 下雨效果

    Rain.gif Android 自定义View(二) 下雨效果 一 实现思路, 雨点用线段表示,通过控制线段的大小和宽度来表示不同的线段. 一个雨点下雨的过程可以表示为一条直线,一次雨点在下雨的过程 ...

  2. 自定义View(二),强大的Canvas

    本文转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android中使用图形处理引擎,2D部分是 ...

  3. Android自定义View(二)

    文章目录 1.构造函数 2.onMeasure() 2.1.MeasureSpec 3.onSizeChanged() 4.onLayout() 5.onDraw() 上一篇: Android自定义V ...

  4. 精通Android自定义View(二十)自定义仿微信扫一扫效果

    1 效果 2 源码 /*** 自动上下扫描*/public class AutoScannerView extends View {private static final String TAG = ...

  5. android自定义view(二)-仿华为卡包效果

    前段时间产品经理出了一个卡列表展示效果,效果的大致样子是仿照华为门禁卡卡包效果,研究了一下大致效果出来了,但和华为比还有点差距,主要是动画不是很流畅,仅供大家参考指正,有好的优化方式也可以告诉我,大家 ...

  6. 自定义view(二) Path绘画详解 圆形进度条

    目录 简介 基础api 圆形进度条 总结 简介 view的绘制可以由无数个形状组成,在canvas基础图形绘制中,我们已经把api提供好的基本图形讲过了.Path之所以单独一章出来是因为path可以由 ...

  7. Android 自定义View绘制的基本开发流程 Android自定义View(二)

    1 View绘制的过程 View的测量--onMeasure() View的位置确定--onLayout() View的绘制--onDraw() 2 View的测量--onMeasure() Andr ...

  8. Android 自定义View二(深入了解自定义属性attrs.xml)

    1.为什么要自定义属性 要使用属性,首先这个属性应该存在,所以如果我们要使用自己的属性,必须要先把他定义出来才能使用.但我们平时在写布局文件的时候好像没有自己定义属性,但我们照样可以用很多属性,这是为 ...

  9. android 网速刻度盘 自定义view二

    这里对上一篇文章另外写的一个http://blog.csdn.net/u012840567/article/details/52860559 转载请标明出处http://blog.csdn.net/u ...

  10. 精通Android自定义View(十二)绘制圆形进度条

    1 绘图基础简析 1 精通Android自定义View(一)View的绘制流程简述 2 精通Android自定义View(二)View绘制三部曲 3 精通Android自定义View(三)View绘制 ...

最新文章

  1. src is not broadcastable to dst, but they have the same number of elements
  2. koa2 mysql sequelize_Vue2+Koa2+Typescript前后端框架教程--05Sequelize(ORM)的使用实现基础的班级增删...
  3. [Zabbix] 怎样实现邮件报警通知以及免费短信报警通知
  4. 浅谈postMessage跨域通信与localStorage实现跨域共享
  5. 拦截导弹(信息学奥赛一本通-T1289)
  6. 为什么要选择基于NAS存储方案
  7. 中累计直方图_新特性解读 | MySQL 8.0 直方图
  8. 【C#】开发可以可视化操作的windows服务
  9. windows jdk8
  10. 【安全牛学习笔记】初识sql注入漏洞原理
  11. mysql 表的增删改查_MySQL数据表的增删改查
  12. Could not load codec 'Lucene54'. Did you forget to add lucene-backward-codecs.jar?
  13. PTA 7-10 查询水果价格
  14. unity 生成和识别二维码
  15. 国内最常用的坐标系大全
  16. 【数据科学家学习小组】之统计学(第二期)第一周(20191028-20191103)-momi
  17. python爬虫——selenium+bs4爬取选股宝‘利好‘or’利空'股票信息
  18. 云计算工程师必备技能
  19. 【机器学习经典算法】K近邻(KNN):核心与总结
  20. Poseidon(海神号)

热门文章

  1. LFU (最不经常使用算法)缓存
  2. yii2高级模板使用一个域名管理前后台(url重写)
  3. android手机到iphone6s,4年前的iPhone6s,相当于现在什么安卓机?很多国产手机尴尬了...
  4. Maya 2018 Arnold在AOV通道中制作运动向量模糊的方法
  5. 可以检测手机帧率和温度的软件_主流手机芯片性能排行,看看哪款可以满足你!...
  6. contains函数
  7. Mac 系统数字小键盘的开启和关闭方式
  8. android修改密码功能,安卓手机设置开机密码几种方法介绍
  9. 关于工具-figma
  10. 非零基础自学Golang 第1章 走进Go 1.1 Go编程语言概述 1.1.2 Go 语言特性及应用场景