自定义View及在配置文件中增加描述属性

有发现一个不错的例子。共享出来:

原文地址:

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>

 

   
posted @ 2012-12-06 00:30  pengqinping  阅读(289)  评论(0编辑  收藏  举报