自定义时钟View,表盘的绘制
来源:互联网 发布:手机快递入库软件 编辑:程序博客网 时间:2024/05/01 00:44
实现的效果图如下:
main中布局文件:
<com.example.drawtime.MyClock android:layout_width="match_parent" android:layout_height="match_parent" />
values文件夹下新建一个xml文件,定义参数
<resources> <declare-styleable name="MyView"> <attr name="MyView_color" format="color"/> <attr name="MyView_radius" format="float"/> </declare-styleable></resources>
1.自定义一个类 MyClock extends View,并设置统一的入口
public MyClock(Context context) { this(context, null); } public MyClock(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyClock(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyView, defStyleAttr, 0); //获得xml属性 color = typedArray.getColor(R.styleable.MyView_MyView_color, CIRCLE_CLOCK); radius = typedArray.getFloat(R.styleable.MyView_MyView_radius, CIRCLE_RADIUS); typedArray.recycle(); }2.测量控件的宽高
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureHeight(int heightMeasureSpec) { int mode = MeasureSpec.getMode(heightMeasureSpec); int size = MeasureSpec.getSize(heightMeasureSpec); if (mode == MeasureSpec.EXACTLY) { heightResult = size; } else { heightResult = 600; if (mode == MeasureSpec.AT_MOST) { heightResult = Math.min(heightResult, size); } } return heightResult; } private int measureWidth(int widthMeasureSpec) { int mode = MeasureSpec.getMode(widthMeasureSpec); int size = MeasureSpec.getSize(widthMeasureSpec); if (mode == MeasureSpec.EXACTLY) { widthResult = size; } else { widthResult = 600;//给一个默认的宽度 if (mode == MeasureSpec.AT_MOST) { widthResult = Math.min(widthResult, size); } } return widthResult; }3.----------------------现在就要开始绘制了---------------------------
我把他们封装为方法
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制表盘 BiaoPan(canvas); //绘制logo Logo(canvas); //绘制数字时间 Time(canvas); //画刻度 drgree(canvas); //画表盘时间数字 HourText(canvas); mHandler.sendEmptyMessage(HANDLER_MSG); //画时针 canvas.save(); hour(canvas); canvas.restore(); //画分针 canvas.save(); minutes(canvas); canvas.restore(); //画秒针 canvas.save(); second(canvas); canvas.restore(); //画中间小点 Point(canvas); }3.1绘制表盘
private void BiaoPan(Canvas canvas) { mBiaoPan = new Paint(); mBiaoPan.setAntiAlias(true); canvas.translate(widthResult / 2, heightResult / 2); mBiaoPan.setStyle(Paint.Style.STROKE); mBiaoPan.setColor(color); mBiaoPan.setStrokeWidth(2); canvas.drawCircle(0, 0, radius, mBiaoPan); }3.2绘制Logo,正负代表方向
private void Logo(Canvas canvas) { mLogoPaint = new TextPaint(); mLogoPaint.setColor(Color.parseColor("#FF4081")); mLogoPaint.setAntiAlias(true); mLogoPaint.setStyle(Paint.Style.STROKE); mLogoPaint.setStrokeWidth(2); mLogoPaint.setTextSize(50); float textwith = mLogoPaint.measureText(BIAO_LOGO); canvas.drawText(BIAO_LOGO, -textwith / 2, -radius / 5 * 2, mLogoPaint); }3.3绘制数字的时间,默认 00:00:00
private void Time(Canvas canvas) { mTimePaint = new Paint(); mTimePaint.setAntiAlias(true); mTimePaint.setColor(Color.GREEN); mTimePaint.setStyle(Paint.Style.FILL); mTimePaint.setTextSize(45); /**根据实际情况我们需要判断下时分秒的数字是不是小于10,如果是前面补一位0*/ if (mSecond < 10) { replaceMsecond = "0" + String.valueOf(mSecond).replace(".0", ""); } else { replaceMsecond = String.valueOf(mSecond).replace(".0", ""); } if (mMinutes < 10) { replaceMminutes = "0" + String.valueOf(mMinutes).replace(".0", ""); } else { replaceMminutes = String.valueOf(mMinutes).replace(".0", ""); } if (mHour < 10) { replaceMhour = "0" + String.valueOf(mHour).replace(".0", ""); } else { replaceMhour = String.valueOf(mHour).replace(".0", ""); } float v = mTimePaint.measureText(replaceMhour + replaceMminutes + replaceMsecond + ":" + ":"); canvas.drawText(replaceMhour + ":" + replaceMminutes + ":" + replaceMsecond, -v / 2, radius / 3 * 2, mTimePaint); }3.4绘制刻度线(让画布旋转)
private void drgree(Canvas canvas) { mDegreePaint = new Paint(); mDegreePaint.setAntiAlias(true); mDegreePaint.setStyle(Paint.Style.FILL); mDegreePaint.setColor(Color.BLACK); mDegreePaint.setStrokeWidth(5); int count = 60; for (int i = 0; i < count; i++) { if (i % 5 == 0) { canvas.drawLine(0, radius, 0, radius - 40, mDegreePaint); } else { canvas.drawLine(0, radius, 0, radius - 15, mDegreePaint); } canvas.rotate(360 / count, 0f, 0f); } }3.5 画表盘上的数字
private void HourText(Canvas canvas) { mHourTextPaint = new Paint(); mHourTextPaint.setStyle(Paint.Style.FILL); mHourTextPaint.setStrokeWidth(2); mHourTextPaint.setAntiAlias(true); mHourTextPaint.setTextSize(55); mHourTextPaint.setColor(Color.DKGRAY); mHourTextPaint.setTextAlign(Paint.Align.CENTER); float textheight = mHourTextPaint.getFontMetrics().bottom - mHourTextPaint.getFontMetrics().top; float distance = radius - 70; float a, b; for (int i = 0; i < 12; i++) { a = (float) (distance * Math.sin(i * 30 * Math.PI / 180)); b = (float) (distance * Math.cos(i * 30 * Math.PI / 180)); if (i == 0) { canvas.drawText("12", a, -b + textheight / 3, mHourTextPaint); } else { canvas.drawText(String.valueOf(i), a, -b + textheight / 3, mHourTextPaint); } } }3.6 发送一条空消息,让时间数字,走起来
@Override public boolean handleMessage(Message message) { switch (message.what) { case HANDLER_MSG: invalidate(); long time = System.currentTimeMillis(); mSecond = (time / 1000 % 60); mMinutes = (time / 1000 / 60 % 60); mHour = (time / 1000 / 60 / 60 + 8) % 12; break; } return true; }
3.7画时针分针秒针(必须要先保存之前的画的,不然会一起动)
private void hour(Canvas canvas) { mHourPaint = new Paint(); mHourPaint.setStrokeWidth(10); mHourPaint.setAntiAlias(true); mHourPaint.setStyle(Paint.Style.FILL); mHourPaint.setColor(Color.RED); canvas.rotate(mHour * 30 + mMinutes / 60 * 30, 0, 0);//其中mMinutes/60*30为时钟偏移的角度 canvas.drawLine(0, 20, 0, -(radius -320), mHourPaint); }private void minutes(Canvas canvas) { mMinutesPaint = new Paint(); mMinutesPaint.setStrokeWidth(8); mMinutesPaint.setAntiAlias(true); mMinutesPaint.setColor(Color.BLUE); mMinutesPaint.setStyle(Paint.Style.FILL); canvas.rotate(mMinutes * 6, 0, 0); canvas.drawLine(0, 20, 0, -(radius - 200), mMinutesPaint); }private void second(Canvas canvas) { //画秒针 mSecondPaint = new Paint(); mSecondPaint.setStrokeWidth(5); mSecondPaint.setAntiAlias(true);//设置抗锯齿 mSecondPaint.setColor(Color.GREEN); mSecondPaint.setStyle(Paint.Style.FILL); canvas.rotate(mSecond * 6, 0, 0); canvas.drawLine(0, 30, 0, -(radius - 100), mSecondPaint); }
3.8 最后在中心画点把指针覆盖private void Point(Canvas canvas) { mPointPaint = new Paint(); mPointPaint.setStrokeWidth(5); mPointPaint.setStyle(Paint.Style.FILL); mPointPaint.setColor(Color.BLACK); canvas.drawCircle(0, 0, 12, mPointPaint); }直接的粘的代码,看的不是很清楚,慢慢看咯
0 0
- 自定义时钟View,表盘的绘制
- 简单的自定义View——表盘时钟
- 自定义view绘制时钟
- 自定义View绘制时钟
- 绘制类似时钟的自定义view
- android studio 绘制时钟刻度表盘的虚拟动画。
- 自定义View 手表表盘
- 自定义View-汽车表盘
- 自定义View之canvas绘制时钟
- 绘制模拟Android钟 ####时钟表盘
- 自定义view的绘制
- 自定义view 的绘制
- Android自定义View——绘制一个会动的时钟
- Android 自定义 View(一) 绘制动态时钟
- 自定义View基础篇——表盘
- android 自定义view实现表盘效果
- Android 自定义View 实现表盘效果
- Android 自定义view(画表盘)
- Xerces -C++ 使用
- 【Mybatis】——mybatis缓存
- service生命周期
- STM32CUBEMX 今天开始学习,标记一下
- [HNOI&AHOI2017] NOIP考挂蒟蒻的一篇游记 && 部分题解
- 自定义时钟View,表盘的绘制
- 用javaConfig注解创建spring 工程的基本配置
- switch proxy ——>Proxy SwitchyOmega
- CSDN博客新手使用方案
- angularjs二、路由配置
- 1.数据包分析技术与网络基础(1)
- MySQ基础L知识-基本操作
- JDK5新特性_枚举的注意事项
- 20170415STL014_STL_迭代器