android自定义控件

Android为开发者提供了大量的控件,这些控件只能满足一般性的需求,有时候需要开发者重新定制控件。控件的定制有三种形式:对原有控件的重写;对原有控件进行组合;自定义新的控件。Android中所有控件类都是View的子类。

本例主要是讲一个自定义时钟控件,该控件直接继承View类。

1.控件类

首先需要编写控件类,该类继承View类,并实现接口Runnable。时钟控件主要包含的参数:clockimageresourceid,scale,handcenterwidthscale,handcenterheightscale,minutehandsize,hourhandsize。

 1 public class HandClock extends View implements Runnable {
 2 
 3     private int clockImageResourceId;//图像资源id
 4     private Bitmap bitmap;//图像资源
 5     private float scale;//图像显示的比例
 6     private float handCenterWidthScale;//横坐标显示比例
 7     private float handCenterHeightScale;//纵坐标显示比例
 8     private int minuteHandSize;//分钟长度
 9     private int hourHandSize;//时针长度
10     private Handler hanlder=new Handler();
11     public HandClock(Context context, AttributeSet attrs) {
12         super(context, attrs);
13         // TODO Auto-generated constructor stub
14         //读取属性值
15         clockImageResourceId=attrs.getAttributeResourceValue(null, "clockImageSrc", 0);
16         if(clockImageResourceId>0)
17         {
18             bitmap=BitmapFactory.decodeResource(getResources(), clockImageResourceId);
19         }
20         scale=attrs.getAttributeFloatValue(null, "scale", 1);
21         handCenterWidthScale=attrs.getAttributeFloatValue(null, "handCenterWidthScale", bitmap.getWidth()/2);
22         handCenterHeightScale=attrs.getAttributeFloatValue(null, "handCenterHeightScale", bitmap.getHeight()/2);
23         minuteHandSize=(int)(attrs.getAttributeIntValue(null, "minuteHandSize",0)*scale);
24         hourHandSize=(int)(attrs.getAttributeIntValue(null, "hourHandSize", 0)*scale);
25         int curentSecond=Calendar.getInstance().get(Calendar.SECOND);
26         hanlder.postDelayed(this, (60-curentSecond)*1000);
27     }
28 
29     protected void onDetachedFromWindow()
30     {
31         super.onDetachedFromWindow();
32         hanlder.removeCallbacks(this);
33     }
34     @Override
35     public void run() {
36         // TODO Auto-generated method stub
37         invalidate();
38         hanlder.postDelayed(this,60*1000);
39     }
40     protected void onMeasure(int widthMeasurespc,int heightMeasurespe)
41     {
42         super.onMeasure(widthMeasurespc, heightMeasurespe);
43         setMeasuredDimension((int)(bitmap.getWidth()*scale),(int)(bitmap.getHeight()*scale));
44         
45     }
46     protected void onDraw(Canvas canvas)
47     {
48         super.onDraw(canvas);
49         Paint paint=new Paint();
50         Rect src=new Rect();
51         Rect target=new Rect();
52         src.left=0;
53         src.top=0;
54         src.right=bitmap.getWidth();
55         src.bottom=bitmap.getHeight();
56         target.left=0;
57         target.top=0;
58         target.bottom=(int)(src.bottom*scale);
59         target.right=(int)(src.right*scale);
60         //画表盘图像
61         canvas.drawBitmap(bitmap, src, target,paint);
62         //计算表盘中心点的横坐标
63         float centerX=bitmap.getWidth()*scale*handCenterWidthScale;
64         //计算表盘中心店的纵坐标
65         float centerY=bitmap.getHeight()*scale*handCenterHeightScale;
66         
67         canvas.drawCircle(centerX, centerY, 5, paint);
68         paint.setStrokeWidth(3);
69         Calendar calendar=Calendar.getInstance();
70         int currentMin=calendar.get(Calendar.MINUTE);
71         int currentHour=calendar.get(Calendar.HOUR);
72         //计算时针和分针角度
73         double minuteRadian=Math.toRadians((360-((currentMin*6)-90))%360);
74         double hourRadian=Math.toRadians((360-((currentHour*30)-90))%360-(30*currentMin/60));
75         //画分针
76         canvas.drawLine(centerX, centerY,(int)(centerX+minuteHandSize*Math.cos(minuteRadian)),(int)(centerY-minuteHandSize*Math.sin(minuteRadian)),paint);
77         paint.setStrokeWidth(4);
78         //画时针
79         canvas.drawLine(centerX, centerY,(int)(centerX+hourHandSize*Math.cos(hourRadian)),(int)(centerY-hourHandSize*Math.sin(hourRadian)),paint);
80     }
81 
82 }

这里面有很多重点,比如说时针与分针角度的计算,重绘的时间等。Runnable接口是软定时器类,这里定义一分钟重绘一次。

2.handclok.xml

在一个xml页面引用刚刚自定义的控件。

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical" >
 5     
 6 <com.example.myandroiddemp.HandClock
 7     android:layout_width="wrap_content"
 8     android:layout_height="wrap_content"
 9     clockImageSrc="@drawable/clock1" 
10     scale="0.7"
11     handCenterWidthScale="0.5"
12     handCenterHeightScale="0.5"
13     minuteHandSize="54"
14     hourHandSize="40"/>
15 
16 </LinearLayout>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android知识点总结

2-VIII--ViewPager滑动监听与自定义滑动特效

13810
来自专栏Android先生

Android自定义View——从零开始实现雪花飘落效果

前言:转眼已是十一月下旬了,天气慢慢转冷,不知道北方是不是已经开始下雪了呢?本期教程我们就顺应季节主题,一起来实现 雪花飘落的效果吧。本篇效果思路参考自国外大神...

17320
来自专栏lzj_learn_note

Android TextView实现查看全部和收起功能

在工作遇到上图所示的一个小需求,将“查看全部”的提示连在原文的后面,使用一个textview显示。实现该功能大致步骤:

1.2K70
来自专栏郭霖

Android多点触控技术实战,自由地对图片进行缩放和移动

在上一篇文章中我带着大家一起实现了Android瀑布流照片墙的效果,虽然这种效果很炫很酷,但其实还只能算是一个半成品,因为照片墙中所有的图片都是只能看不能点的。...

28550
来自专栏三流程序员的挣扎

Android 动画总结(9) - 过渡动画

前面已经介绍过一部分 Activity 之间的过渡动画。现在讲的不是 Activity 转场,而是同一个页面的 View 之间的过渡。

50010
来自专栏Android点滴积累

Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

  一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景。但是,也肯...

13500
来自专栏Sorrower的专栏

Android绘制(一):来用shape绘出想要的图形吧!

24140
来自专栏郭霖

Android PowerImageView实现,可以播放动画的强大ImageView

我个人是比较喜欢逛贴吧的,贴吧里总是会有很多搞笑的动态图片,经常看一看就会感觉欢乐很多,可以释放掉不少平时的压力。确实,比起一张单调的图片,动态图片明显更加的有...

31350
来自专栏静晴轩

Drawable.Bitmap.Canvas.Paint.Matrix

由于对Drawable、Bitmap、Canvas、Paint和 Matrix 的关系和使用 一直不太清楚,就在网上搜集了一下,摘录一些,主要来看这两篇文章:D...

38760
来自专栏一“技”之长

Android开发中TableLayout表格布局

        在移动端应用程序开发中,常常会使用到表格布局,iOS和Android开发框架中都提供了独立的表格视图控件供开发者使用,例如iOS中的UITabl...

12230

扫码关注云+社区

领取腾讯云代金券