自定义View的类必须继承自View并且重写onDraw(Canvas canvas)方法; 增加自定义的属性描述必须在values中增加attrs.xml来描述View的属性;
[图片] 3f7f41d4g9f496933f377&690.jpg
[代码] [XML]代码
01
<?xml version="1.0" encoding="UTF-8"?>
02
<resources>
03
<declare-styleable name="ClockView">
04
<attr name="clockColor" format="color" />
05
<attr name="visible" format="boolean"/>
06
<attr name="timeZone" format="dimension">
07
<enum name="londan" value="0" />
08
<enum name="beijing" value="8" />
09
<enum name="newyork" value="20" />
10
</attr>
11
</declare-styleable>
12
</resources>
[代码] [XML]代码
01
<?xml version="1.0" encoding="utf-8"?>
02
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03
xmlns:joydao="http://schemas.android.com/apk/res/net.joydao.clock"
04
android:orientation="vertical" android:layout_width="fill_parent"
05
android:layout_height="fill_parent">
06
07
08
09
<net.joydao.clock.view.ClockView
10
android:id="@+id/joydaoClock" android:layout_width="wrap_content"
11
android:layout_height="wrap_content" joydao:clockColor="#ffffff"
12
joydao:visible="false" joydao:timeZone="beijing" />
13
14
</LinearLayout>
[文件] ClockView.java ~ 10KB下载(21)
001
package net.joydao.clock.view;
002
003
import java.text.DateFormat;
004
import java.text.SimpleDateFormat;
005
import java.util.Calendar;
006
import java.util.Date;
007
import java.util.TimeZone;
008
009
import net.joydao.clock.R;
010
011
import android.content.Context;
012
import android.content.res.TypedArray;
013
import android.graphics.Canvas;
014
import android.graphics.Color;
015
import android.graphics.Paint;
016
import android.util.AttributeSet;
017
import android.util.DisplayMetrics;
018
import android.view.View;
019
import android.view.WindowManager;
020
021
public class ClockView extends View implements Runnable {
022
023
private Paint colorCirclePaint;
024
private Paint pointPaint;
025
private Paint hourMarkPaint;
026
private Paint minuteMarkPaint;
027
private Paint secondNeedlePaint;
028
private Paint minuteNeedlePaint;
029
private Paint hourNeedlePaint;
030
private Paint textPaint;
031
private Paint timePaint;
032
private float hourMarkLen;
033
private float minuteMarkLen;
034
private float clockCircle;
035
private float radius;
036
private float hourNeedleRadius;
037
private float minuteNeedleRadius;
038
private float secondNeedleRadius;
039
private float cx;
040
private float cy;
041
private boolean running = false;
042
private int mYear;
043
private int mMonth;
044
private int mDay;
045
private int mHour;
046
private int mMinute;
047
private int mSecond;
048
private int clockColor;
049
050
public ClockView(Context context){
051
this(context,null);
052
}
053
054
public ClockView(Context context, AttributeSet attrs) {
055
super(context, attrs);
056
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.ClockView);
057
clockColor = typedArray.getColor(R.styleable.ClockView_clockColor, Color.WHITE);
058
typedArray.recycle();
059
pointPaint = new Paint();
060
pointPaint.setAntiAlias(true);
061
pointPaint.setStyle(Paint.Style.STROKE);
062
063
colorCirclePaint = new Paint();
064
colorCirclePaint.setTextAlign(Paint.Align.CENTER);
065
colorCirclePaint.setAntiAlias(true);
066
colorCirclePaint.setStrokeWidth(clockCircle);
067
colorCirclePaint.setStyle(Paint.Style.STROKE);
068
069
hourMarkPaint = new Paint();
070
hourMarkPaint.setTextAlign(Paint.Align.CENTER);
071
hourMarkPaint.setAntiAlias(true);
072
hourMarkPaint.setStyle(Paint.Style.STROKE);
073
074
minuteMarkPaint = new Paint();
075
minuteMarkPaint.setTextAlign(Paint.Align.CENTER);
076
minuteMarkPaint.setAntiAlias(true);
077
minuteMarkPaint.setStyle(Paint.Style.STROKE);
078
079
secondNeedlePaint = new Paint();
080
secondNeedlePaint.setTextAlign(Paint.Align.CENTER);
081
secondNeedlePaint.setAntiAlias(true);
082
secondNeedlePaint.setStyle(Paint.Style.STROKE);
083
084
minuteNeedlePaint = new Paint();
085
minuteNeedlePaint.setTextAlign(Paint.Align.CENTER);
086
minuteNeedlePaint.setAntiAlias(true);
087
minuteNeedlePaint.setStyle(Paint.Style.STROKE);
088
089
hourNeedlePaint = new Paint();
090
hourNeedlePaint.setTextAlign(Paint.Align.CENTER);
091
hourNeedlePaint.setAntiAlias(true);
092
hourNeedlePaint.setStyle(Paint.Style.STROKE);
093
094
textPaint = new Paint();
095
textPaint.setTextAlign(Paint.Align.CENTER);
096
textPaint.setAntiAlias(true);
097
098
timePaint = new Paint();
099
timePaint.setTextAlign(Paint.Align.CENTER);
100
timePaint.setAntiAlias(true);
101
start();
102
}
103
104
public int getClockColor() {
105
return clockColor;
106
}
107
108
public void setClockColor(int clockColor) {
109
this.clockColor = clockColor;
110
this.postInvalidate();
111
}
112
113
public void start(){
114
running = true;
115
new Thread(this).start();
116
}
117
118
public void stop(){
119
running = false;
120
}
121
122
private void resetTime(){
123
Calendar c = Calendar.getInstance(TimeZone.getDefault());
124
c.setTime(new Date());
125
mYear = c.get(Calendar.YEAR);
126
mMonth = c.get(Calendar.MONTH)+1;
127
mDay = c.get(Calendar.DAY_OF_MONTH);
128
mHour = c.get(Calendar.HOUR_OF_DAY);
129
mMinute = c.get(Calendar.MINUTE);
130
mSecond = c.get(Calendar.SECOND);
131
}
132
133
@Override
134
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
135
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
136
}
137
138
@Override
139
protected void onDraw(Canvas canvas) {
140
super.onDraw(canvas);
141
pointPaint.setColor(clockColor);
142
colorCirclePaint.setColor(clockColor);
143
hourMarkPaint.setColor(clockColor);
144
minuteMarkPaint.setColor(clockColor);
145
secondNeedlePaint.setColor(clockColor);
146
minuteNeedlePaint.setColor(clockColor);
147
hourNeedlePaint.setColor(clockColor);
148
textPaint.setColor(clockColor);
149
timePaint.setColor(clockColor);
150
cx = getWidth()/2;
151
cy = getHeight()/2;
152
int tmp = getWidth()<=getHeight()?getWidth():getHeight();
153
radius = tmp/2-2*clockCircle;
154
hourMarkLen = radius/15;
155
minuteMarkLen = radius/30;
156
clockCircle = radius/60;
157
pointPaint.setStrokeWidth(radius/25);
158
textPaint.setTextSize(radius/8);
159
timePaint.setTextSize(radius/5);
160
hourMarkPaint.setStrokeWidth(radius/35);
161
minuteMarkPaint.setStrokeWidth(radius/70);
162
secondNeedlePaint.setStrokeWidth(radius/70);
163
minuteNeedlePaint.setStrokeWidth(radius/35);
164
hourNeedlePaint.setStrokeWidth(radius/20);
165
hourNeedleRadius = radius - radius/2;
166
minuteNeedleRadius = radius - radius/3;
167
secondNeedleRadius = radius - radius/5;
168
drawClockPanel(canvas,radius);
169
drawNeedle(canvas);
170
drawTime(canvas);
171
}
172
173
private void drawTime(Canvas canvas){
174
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
175
DateFormat timeFormat = new SimpleDateFormat("hh:mm:ss a");
176
String dateText = dateFormat.format(new Date());
177
String timeText = timeFormat.format(new Date());
178
float textX = cx;
179
float timeY = cy+radius/2;
180
float dateY = timeY+1.5f*textPaint.getTextSize();
181
canvas.drawText(dateText, textX, dateY, textPaint);
182
canvas.drawText(timeText, textX, timeY, timePaint);
183
}
184
185
private void drawClockPanel(Canvas canvas,float radius){
186
//System.out.println(getWidth()+":"+getHeight());
187
//画钟的外圈
188
canvas.drawCircle(cx, cy, radius, colorCirclePaint);
189
//画钟的圆点
190
canvas.drawCircle(cx, cy, radius/60, pointPaint);
191
int hourLen = 12;
192
int minLen = 60;
193
for(int index = 0;index<hourLen;index++){
194
drawMark(canvas,index,cx,cy,radius,radius-hourMarkLen,(2*Math.PI/hourLen)*index+Math.PI/2,hourMarkPaint,true);
195
}
196
for(int index = 0;index<minLen;index++){
197
drawMark(canvas,index,cx,cy,radius,radius-minuteMarkLen,(2*Math.PI/minLen)*index+Math.PI/2,minuteMarkPaint,false);
198
}
199
}
200
201
private void drawNeedle(Canvas canvas){
202
double hourAngle = (2*Math.PI/12)*mHour+Math.PI/2+((2*Math.PI)/(12*60))*mMinute+((2*Math.PI)/(12*60*60))*mSecond;
203
double minuteAngle = (2*Math.PI/(12*5))*mMinute+Math.PI/2+((2*Math.PI)/(12*5*60))*mSecond;
204
double secondAngle = (2*Math.PI/60)*mSecond+Math.PI/2;
205
drawNeedle(canvas,cx,cy,hourAngle,hourNeedleRadius,hourNeedlePaint);
206
drawNeedle(canvas,cx,cy,minuteAngle,minuteNeedleRadius,minuteNeedlePaint);
207
drawNeedle(canvas,cx,cy,secondAngle,secondNeedleRadius,secondNeedlePaint);
208
}
209
210
private void drawMark(Canvas canvas,int index,float cx,float cy,float r1,floatr2,double angle,Paint paint,boolean drawNumber){
211
float startX = (float)(cx-r2*Math.cos(angle));
212
float startY = (float)(cy-r2*Math.sin(angle));
213
float stopX = (float)(cx-r1*Math.cos(angle));
214
float stopY = (float)(cy-r1*Math.sin(angle));
215
float textSize = textPaint.getTextSize();
216
float radiusText = r2 - textSize;
217
if(index>=3 && index<=9){
218
radiusText = r2-textSize/3;
219
}
220
float textX = (float)(cx-radiusText*Math.cos(angle));
221
float textY = (float)(cy-radiusText*Math.sin(angle));
222
if(index == 3 || index == 9){
223
textY = textY + textSize/4;
224
}
225
canvas.drawLine(startX,startY,stopX,stopY, paint);
226
if(drawNumber){
227
if(index==0){
228
index = 12;
229
}
230
canvas.drawText(String.valueOf(index), textX, textY, textPaint);
231
}
232
}
233
234
private void drawNeedle(Canvas canvas,float cx,float cy,double angle,floatradius,Paint paint){
235
canvas.drawLine(cx, cy, (float)(cx-radius*Math.cos(angle)), (float)(cy-radius*Math.sin(angle)), paint);
236
}
237
238
public static Screen getScreenPix(Context context) {
239
DisplayMetrics dm = new DisplayMetrics();
240
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
241
windowManager.getDefaultDisplay().getMetrics(dm);
242
return new Screen(dm.widthPixels,dm.heightPixels);
243
}
244
245
public static class Screen{
246
247
public int widthPixels;
248
public int heightPixels;
249
250
public Screen(){
251
252
}
253
254
public Screen(int widthPixels,int heightPixels){
255
this.widthPixels=widthPixels;
256
this.heightPixels=heightPixels;
257
}
258
259
@Override
260
public String toString() {
261
return "("+widthPixels+","+heightPixels+")";
262
}
263
264
}
265
266
@Override
267
public void run() {
268
while(running){
269
try {
270
resetTime();
271
postInvalidate();
272
Thread.sleep(1000);
273
} catch (InterruptedException e) {
274
e.printStackTrace();
275
}
276
}
277
}
278
279
}
[代码] main.xml
01
<?xml version="1.0" encoding="utf-8"?>
02
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03
xmlns:joydao="http://schemas.android.com/apk/res/net.joydao.clock"
04
android:orientation="vertical" android:layout_width="fill_parent"
05
android:layout_height="fill_parent">
06
07
<net.joydao.clock.view.ClockView
08
android:id="@+id/joydaoClock" android:layout_width="wrap_content"
09
android:layout_height="wrap_content" joydao:clockColor="#ffffff"
10
joydao:visible="false" joydao:timeZone="beijing" />
11
12
</LinearLayout>
[代码] attrs.xml
01
<?xml version="1.0" encoding="UTF-8"?>
02
<resources>
03
<declare-styleable name="ClockView">
04
<attr name="clockColor" format="color" />
05
<attr name="visible" format="boolean"/>
06
<attr name="timeZone" format="dimension">
07
<enum name="londan" value="0" />
08
<enum name="beijing" value="8" />
09
<enum name="newyork" value="20" />
10
</attr>
11
</declare-styleable>
12
</resources>