自定义View(二)
2016-07-03 23:57
232 查看
一、概述
在上一篇分析了自定义View的基础知识,如果还是不清楚自定义View的请看上篇博客自定义View(一)。这篇主要是一个自定View的一个简单实例—-一个时钟效果。运行如下。其实这个效果之前写过一篇网页版的,利用HTML5的context写的,有兴趣的可以看看。
简单分析下:
由图可以看出这个自定义View由一个圆,3个指针直线,然后就是断直线了,至于它的自动走动可以用post系列方法重复调用onDraw即可。这里的重点是canvas的rotate、translate两个方法的灵活使用。
二、代码
布局如下:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.lw.myclock.MyClock android:layout_width="300dp" android:layout_height="300dp" /> </RelativeLayout>
初始化方法,用来创建画笔,并且设置画笔的style和颜色
public void init(){ mPaint.setColor(Color.BLUE); mPaint.setStyle(Style.STROKE); //去掉锯齿 mPaint.setAntiAlias(true); mPaint.setStrokeWidth(3); }
获取当前时间
//获取当前时间 d = new Date(); int hours = d.getHours(); int minutes = d.getMinutes();
下面则是开始真正画了,主要是通过canvas的translate()来设置画布的中心点,然后调用rotat()e控制画布旋转来画出短线。
//1.画圆 canvas.translate(150, 150); canvas.drawCircle(0, 0, radius, mPaint); //2.画时钟刻度线 for (int i = 0; i <= 11 ; i++) { mPaint.setStrokeWidth(3); canvas.drawLine(0, -150, 0, -135, mPaint) ; mPaint.setStrokeWidth(1); if( i == 0 ){ canvas.drawText(12 + "",-5,-130,mPaint) ; }else{ canvas.drawText(i + "",-5,-130,mPaint) ; } canvas.rotate(30) ; } //画分钟刻度线 for (int i = 0; i < 60 ; i++) { mPaint.setStrokeWidth(1) ; canvas.drawLine(0, -150, 0, -145, mPaint) ; canvas.rotate(6); }
这里每次开始画之前需要调用save()方法,每次画好之后需要调用restore()方法
//画时钟刻度指针 canvas.save() ; mPaint.setStrokeWidth(4); canvas.rotate(hours * 30 + (minutes * 6) * 30 / 360 ); canvas.drawLine(0, 10, 0, -90, mPaint); canvas.restore() ; //画分钟刻度指针 canvas.save() ; mPaint.setStrokeWidth(2); //初始化分钟指针,主要让其指定到12点位置 System.out.println("minutes:" + minutes * 6 ); canvas.rotate(minutes * 6 ) ; canvas.drawLine(0, 10, 0, -100, mPaint); canvas.restore() ; //画秒钟刻度线 canvas.save() ; mPaint.setStrokeWidth(1); canvas.rotate(seconds * 6 ); System.out.println("seconds:" + seconds); canvas.drawLine(0, 10, 0, -120, mPaint) ; canvas.restore() ; //画中心圆点 canvas.save() ; mPaint.setStrokeWidth(3); canvas.drawCircle(0, 0, 2, mPaint); canvas.restore() ;
这里比较复杂的是时钟角度的变化
canvas.rotate(hours * 30 + (minutes * 6) * 30 / 360 ) ;
假如此时时间是11点30分,11点则是hours * 30,30分钟旋转的角度则是 (minutes * 6) * 30 / 360 。
然后就开始调用post方法每一个1s调用。
全部代码如下:
package com.lw.myclock;
import java.util.Date;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;
/**
* 自定义时钟
* @author lw
*
*/
public class MyClock extends View {
private Paint mPaint = new Paint();
private Date d;
public MyClock(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyClock(Context context) {
this(context,null);
}
public void init(){ mPaint.setColor(Color.BLUE); mPaint.setStyle(Style.STROKE); //去掉锯齿 mPaint.setAntiAlias(true); mPaint.setStrokeWidth(3); }
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
int paddingBottom = getPaddingBottom();
int paddingTop = getPaddingTop();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
width = width - paddingLeft - paddingRight ;
height = height - paddingBottom - paddingTop ;
//300 300
//获取当前时间
d = new Date();
int hours = d.getHours();
int minutes = d.getMinutes();
int seconds = d.getSeconds();
int radius = Math.min(width, height) / 2 ;//1.画圆 canvas.translate(150, 150); canvas.drawCircle(0, 0, radius, mPaint); //2.画时钟刻度线 for (int i = 0; i <= 11 ; i++) { mPaint.setStrokeWidth(3); canvas.drawLine(0, -150, 0, -135, mPaint) ; mPaint.setStrokeWidth(1); if( i == 0 ){ canvas.drawText(12 + "",-5,-130,mPaint) ; }else{ canvas.drawText(i + "",-5,-130,mPaint) ; } canvas.rotate(30) ; } //画分钟刻度线 for (int i = 0; i < 60 ; i++) { mPaint.setStrokeWidth(1) ; canvas.drawLine(0, -150, 0, -145, mPaint) ; canvas.rotate(6); }//画时钟刻度指针
canvas.save() ;
mPaint.setStrokeWidth(4);
canvas.rotate(hours * 30 + (minutes * 6) * 30 / 360 ) ;
canvas.drawLine(0, 10, 0, -90, mPaint);
canvas.restore() ;
//画分钟刻度指针
canvas.save() ;
mPaint.setStrokeWidth(2);
//初始化分钟指针,主要让其指定到12点位置
System.out.println("minutes:" + minutes * 6 );
canvas.rotate(minutes * 6 ) ;
canvas.drawLine(0, 10, 0, -100, mPaint);
canvas.restore() ;
//画秒钟刻度线
canvas.save() ;
mPaint.setStrokeWidth(1);
canvas.rotate(seconds * 6 );
System.out.println("seconds:" + seconds);
canvas.drawLine(0, 10, 0, -120, mPaint) ;
canvas.restore() ;
//画中心圆点
canvas.save() ;
mPaint.setStrokeWidth(3);
canvas.drawCircle(0, 0, 2, mPaint);
canvas.restore() ;
//递归调用
postInvalidateDelayed(1000) ;
}
}
OK,这个简单实例到这就结束了。
源码下载
相关文章推荐
- OpenGL学习脚印: 光照中材质和lighting maps使用(material and lighting maps)
- 【leetcode】204. Count Primes
- PKCS5Padding与PKCS7Padding的区别
- 通过blktrace, debugfs分析磁盘IO
- LeetCode第3题
- 浅谈C++类(7)--析构函数
- 径向基网络(RBF network)之BP监督训练
- Spring AOP定义以及注解形式实现
- C++中的rand()、srand()
- losetup命令:设置循环设备
- [git] github 使用简单记录
- iOS --- 协议部分(swift2.3)
- 机器学习:核函数的一个小题目
- Hadoop初学笔记
- 千百万以上海量连接的select、poll和epoll等网络I/O模型的性能测试与分析提纲
- 3.2.8 虚拟内存管理
- linux系统卸载openJDK操作步骤
- 图论(网络流,分数规划):COGS 2047. [ZOJ2676]网络战争
- Linux输入子系统(Input Subsystem)
- 对这次实习的想法