Android-自定义控件之时针-霞辉
注释已经比较详细了,废话就不多说了。贴代码了
时针分针秒钟都做上去了,采用的方法也很简单,仔细看一会就能看懂
自定义View类
package com.xh.mytime;
import java.util.Calendar;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
public class MyTimeTest  extends View implements Runnable
{
	private int srcId;
	private int fensize;
	private int shisize;
	private int miaosize;
	private Bitmap bitmap;
	private float guimo;
	private float wzhong;
	private float hzhong;
private Handler handler = new Handler();
/*
	 * */
	public MyTimeTest(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		// 读取相应的属性值
		//在布局文件中定义了这样的一个属性,取得它的属性值,该属性值指向一张图片,通过bitmapFactory获得由它制定的图片bitmap
		srcId = attrs.getAttributeResourceValue(null,
				"Src", 0);
		if (srcId > 0)
			bitmap = BitmapFactory.decodeResource(getResources(),
					srcId);
		
		guimo = attrs.getAttributeFloatValue(null, "scale", 1);
		//获取xml文件中的图片宽度中点,如果没有设置则说明图片是对称的。取默认返回参数
		wzhong = attrs.getAttributeFloatValue(null,
				"wzhong", bitmap.getWidth() / 2);
		//获取xml文件中的图片高度中点,如果没有设置则说明图片是对称的。取默认返回参数
		hzhong = attrs.getAttributeFloatValue(null,
				"hzhong", bitmap.getHeight() / 2);
		//获取到时针和分针的大小
		fensize = (int) (attrs.getAttributeIntValue(null,
				"fensize", 0));
		shisize = (int) (attrs.getAttributeIntValue(null, "shisize",
				0));
		miaosize = (int)(attrs.getAttributeIntValue(null, "miaosize", 0));
		
		
	}
	//刷新,保证能接受到每一次view的变化.
	@Override
	public void run()
	{
		// 重新绘制View
		invalidate();
handler.postDelayed(this, 1000);
	}
//如果不覆盖此方法,默认的会将view铺满整个屏幕
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		// 根据图像的实际大小等比例设置View的大小
		setMeasuredDimension((int) (bitmap.getWidth() * guimo), (int) (bitmap
				.getHeight() * guimo));
	}
@Override
	protected void onDraw(Canvas canvas)
	{
		super.onDraw(canvas);
		//笔
		Paint paint = new Paint();
		//矩形
		Rect src = new Rect();
		Rect target = new Rect();
		
		src.left = 0;
		src.top = 0;
		src.right = bitmap.getWidth();
		src.bottom = bitmap.getHeight();
target.left = 0;
		target.top = 0;
		target.bottom = (int) (src.bottom * guimo);
		target.right = (int) (src.right * guimo);
		// 画表盘图像
		/*
		 * dai
		 * */
		canvas.drawBitmap(bitmap, src, target, paint);
		// 计算表盘中心点的横纵坐标
		float centerX = bitmap.getWidth() * guimo * wzhong;
		float centerY = bitmap.getHeight() * guimo * hzhong;
		// 表表盘中心点画一个半径为5的实心圆圈
		canvas.drawCircle(centerX, centerY, 5, paint);
		
		
		
		
		Calendar calendar = Calendar.getInstance();
		
		int currentMinute = calendar.get(Calendar.MINUTE);
		int currentHour = calendar.get(Calendar.HOUR);
		int currentsec = calendar.get(Calendar.SECOND);
		// 计算分针和时间的角度
double hourRadian = Math.toRadians(
				(360 - ((currentHour * 30) - 90))% 360 - (30 * currentMinute / 60)
				);
double minuteRadian = Math.toRadians(
				(360 - ((currentMinute * 6) - 90)) % 360
				);
		double secRadian = Math.toRadians(
				(360 - ((currentsec * 6) - 90))% 360
				);
		// 在表盘上画分针
		
		paint.setStrokeWidth(6);
		// 在表盘上画分针
		canvas.drawLine(centerX, centerY, (int) (centerX + shisize
				* Math.cos(hourRadian)), (int) (centerY - shisize
				* Math.sin(hourRadian)), paint);
		paint.setStrokeWidth(5);
		
		canvas.drawLine(centerX, centerY, (int) (centerX + fensize
				* Math.cos(minuteRadian)), (int) (centerY - fensize
				* Math.sin(minuteRadian)), paint);
		// 设置实针为4个象素粗
		
		paint.setStrokeWidth(4);
		canvas.drawLine(centerX, centerY, (int) (centerX + miaosize
				* Math.cos(secRadian)), (int) (centerY - miaosize
				* Math.sin(secRadian)), paint);
		
		handler.postDelayed(this, 1000);
	}
}
布局
<LinearLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.xh.mytimetest.MainActivity" 
    android:orientation="vertical"
    android:gravity="center">
<com.xh.mytime.MyTimeTest
        android:id="@+id/myTimeTest2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        Src="@drawable/mytime"
        hzhong="0.512"
        wzhong="0.505"
        shisize="65"
        fensize="80"
        guimo="0.75"
        miaosize="95" 
        android:clickable="true"/>
</LinearLayout>
源代码上传,另外包含一个数字时针,点击可跳转
http://files.cnblogs.com/files/1124hui/MyTime.zip
Android-自定义控件之时针-霞辉的更多相关文章
- Android getAttributeIntValue()详解-霞辉
		
经常使用getAttributeIntValue()方法,但是大多使用的形式是attrs.getAttributeFloatValue(null, "xxx", 0);只是在中间传 ...
 - Android自定义控件之自定义ViewGroup实现标签云
		
前言: 前面几篇讲了自定义控件绘制原理Android自定义控件之基本原理(一),自定义属性Android自定义控件之自定义属性(二),自定义组合控件Android自定义控件之自定义组合控件(三),常言 ...
 - Android自定义控件之自定义组合控件
		
前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...
 - Android自定义控件之自定义属性
		
前言: 上篇介绍了自定义控件的基本要求以及绘制的基本原理,本篇文章主要介绍如何给自定义控件自定义一些属性.本篇文章将继续以上篇文章自定义圆形百分比为例进行讲解.有关原理知识请参考Android自定义控 ...
 - Android自定义控件之基本原理
		
前言: 在日常的Android开发中会经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件,今天先大致了解一下自定义控件的要求和实现的基本原理. 自 ...
 - Android自定义控件1
		
概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...
 - 一起来学习Android自定义控件1
		
概述 Android已经为我们提供了大量的View供我们使用,但是可能有时候这些组件不能满足我们的需求,这时候就需要自定义控件了.自定义控件对于初学者总是感觉是一种复杂的技术.因为里面涉及到的知识点会 ...
 - [Xamarin.Android] 自定义控件
		
[Xamarin.Android] 自定义控件 前言 软件项目开发的过程中,免不了遇到一些无法使用内建控件就能满足的客户需求,例如:时速表.折线图...等等.这时开发人员可以透过自定义控件的方式,为项 ...
 - android自定义控件实现TextView按下后字体颜色改变
		
今天跟大家分享一下Android自定义控件入门,先介绍一个简单的效果TextView,按下改变字体颜色,后期慢慢扩展更强大的功能 直接看图片 第一张是按下后截的图,功能很简单, ...
 
随机推荐
- API网关Ocelot 使用Polly 处理部分失败问题
			
在实现API Gateway过程中,另外一个需要考虑的问题就是部分失败.这个问题发生在分布式系统中当一个服务调用另外一个服务超时或者不可用的情况.API Gateway不应该被阻断并处于无限期等待下游 ...
 - 编写JQuery插件-2
			
继续上一节的代码 (function(){ /* code */ })() 来我们介绍一下吧,首先定义一个匿名函数 fnction(){/* 这里放置代码 */} 然后用括号括起来, (fnction ...
 - ScrollView嵌套ListView显示不完全、嵌套TextView不能滚动解决办法
			
目录: 一.情景说明 二.最初做法 三.解决办法 一.情景说明 1.情景 最近项目刚好有一个需求,需要在一个界面中用ScrollView嵌套一个滚动的TextView和一个listView ...
 - linux下读取系统内存的demo
			
#include <stdio.h> #define KIBIBYTE_SIZE 1024LL #define MEBIBYTE_SIZE 1048576LL #define GIBIBY ...
 - FZU 2167 大王叫我来巡山呐
			
Problem 2167 大王叫我来巡山呐 Accept: 931 Submit: 1405Time Limit: 1000 mSec Memory Limit : 32768 KB Pr ...
 - Maven常用插件简单配置
			
好久不见,甚是想念.一日不见,如隔三秋. 从春节到现在已经很久没有回归博客园了,今天回来温习一下maven常用的一些插件的配置,学东西一个很简单的诀窍就是重复重复再重复,这样一定能把知识掌握的很牢靠. ...
 - Extjs grid 组件
			
表格面板类Ext.grid.Panel 重要的配置参数 columns : Array 列模式(Ext.grid.column.Columnxtype: gridcolumn) 重要的配置参数 tex ...
 - groovy学习(二)map
			
names = ['Ken' : 'Barclay', 'John' : 'Savage']divisors = [4 : [2], 6 : [3, 2], 12 : [6, 4, 3, 2]]pri ...
 - 从0移植uboot (二) _启动流程分析
			
经过了上一篇的配置,我们已经执行make就可以编译出一个uboot.bin,但这还不够,首先,此时的uboot并不符合三星芯片对bootloader的格式要求,其次,此时的uboot.bin也没有结合 ...
 - windows下读取utf-8文件
			
#include <stdio.h> #include <tchar.h> #include <memory> int main() { FILE* fp1 = f ...