有发现一个不错的例子。共享出来:
原文地址:
http://www.oschina.net/code/snippet_54100_5506
[代码] [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
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,floatr1,float r2,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,doubleangle,float radius,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>