使用自定義View
屬性attrs文件如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="WatchView">
<attr name="watchRadius" format="dimension"/> //錶盤半徑
<attr name="watchPadding" format="dimension"/> //錶盤相對控件邊框距離
<attr name="watchScalePadding" format="dimension"/> //刻度相對錶盤距離
<attr name="watchScaleColor" format="color|reference"/> //常規刻度顏色
<attr name="watchScaleLength" format="dimension|reference"/> //常規刻度長度
<attr name="watchHourScaleColor" format="dimension|reference"/> //錶盤整點刻度顏色
<attr name="watchHourScaleLength" format="dimension|reference"/> //整點刻度長度
<attr name="hourPointColor" format="color|reference"/> //時針顏色
<attr name="hourPointLength" format="dimension|reference"/> //時針長度
<attr name="minutePointColor" format="color|reference"/> //分針顏色
<attr name="minutePointLength" format="dimension|reference"/> //分針長度
<attr name="secondPointColor" format="color|reference"/> //秒針顏色
<attr name="secondPointLength" format="dimension|reference"/> //秒針長度
<attr name="timeTextSize" format="dimension|reference"/> //錶盤字體大小
<attr name="timeTextColor" format="color|reference"/> //錶盤字體顏色
</declare-styleable>
</resources>
自定義View文件
public class WatchView extends View{
/**錶盤邊距*/
private float mWatchPadding = 5;
/**錶盤與刻度邊距*/
private float mWatchScalePadding = 5;
/**錶盤半徑*/
private float mWatchRadius = 250;
/**錶盤刻度長度*/
private float mWatchScaleLength = 5;
/**錶盤刻度顏色*/
private int mWatchScaleColor = Color.BLACK;
/**錶盤整點刻度長度*/
private float mHourScaleLength = 8;
/**錶盤整點刻度顏色*/
private int mHourScaleColor = Color.BLUE;
/**錶盤時針顏色*/
private int mHourPointColor = Color.BLACK;
/**錶盤時針長度*/
private float mHourPointLength = 100;
/**錶盤分針顏色*/
private int mMinutePointColor = Color.BLACK;
/**錶盤分針長度*/
private float mMinutePointLength = 130;
/**錶盤秒針顏色*/
private int mSecondPointColor = Color.RED;
/**錶盤秒針長度*/
private float mSecondPointLength = 160;
/**錶盤尾部指針長度*/
private float mEndPointLength;
/**錶盤數字顏色*/
private int mTimeTextColor = Color.BLACK;
/**錶盤數字大小*/
private int mTimeTextSize = 15;
private Paint mPaint;
private String[] mTimes = {"XII","Ⅰ","Ⅱ","Ⅲ","Ⅳ","Ⅴ","Ⅵ","Ⅶ","Ⅷ","Ⅸ","Ⅹ","XI"};
private Paint mHourPaint;
private Paint mMinutePaint;
private Paint mSecondPaint;
public WatchView(Context context) {
super(context);
}
public WatchView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.WatchView);
int n = array.getIndexCount();
for (int i = 0;i<n;i++){
int attr = array.getIndex(i);
switch (attr){
case R.styleable.WatchView_watchRadius:
mWatchRadius = array.getDimensionPixelSize(attr, dp2px(context,60));
break;
case R.styleable.WatchView_watchPadding:
mWatchPadding = array.getDimensionPixelSize(attr,dp2px(context,5));
break;
case R.styleable.WatchView_watchScalePadding:
mWatchScalePadding = array.getDimensionPixelSize(attr,dp2px(context,3));
break;
case R.styleable.WatchView_watchScaleLength:
mWatchScaleLength = array.getDimensionPixelSize(attr,dp2px(context,5));
break;
case R.styleable.WatchView_watchScaleColor:
mWatchScaleColor = array.getColor(attr, Color.parseColor("#50000000"));
break;
case R.styleable.WatchView_watchHourScaleLength:
mHourScaleLength = array.getDimensionPixelSize(attr,dp2px(context,10));
break;
case R.styleable.WatchView_watchHourScaleColor:
mHourScaleColor = array.getColor(attr,Color.BLACK);
break;
case R.styleable.WatchView_hourPointLength:
mHourPointLength = array.getDimensionPixelSize(attr,dp2px(context,35));
break;
case R.styleable.WatchView_hourPointColor:
mHourPointColor = array.getColor(attr,Color.BLACK);
break;
case R.styleable.WatchView_minutePointLength:
mMinutePointLength = array.getDimensionPixelSize(attr,dp2px(context,40));
break;
case R.styleable.WatchView_minutePointColor:
mMinutePointColor = array.getColor(attr,Color.BLACK);
break;
case R.styleable.WatchView_secondPointLength:
mSecondPointLength = array.getDimensionPixelSize(attr,dp2px(context,50));
break;
case R.styleable.WatchView_secondPointColor:
mSecondPointColor = array.getColor(attr,Color.BLUE);
break;
case R.styleable.WatchView_timeTextSize:
mTimeTextSize = array.getDimensionPixelSize(attr,dp2px(context,15));
break;
case R.styleable.WatchView_timeTextColor:
mTimeTextColor = array.getColor(attr,Color.BLACK);
break;
}
}
array.recycle();
}
public WatchView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int wrapContentSize = 1000;
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED && heightMode == MeasureSpec.UNSPECIFIED){
wrapContentSize = (int) Math.max(wrapContentSize,mWatchRadius+mWatchPadding);
setMeasuredDimension(wrapContentSize,wrapContentSize);
}else {
setMeasuredDimension(widthSize,heightSize);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(getWidth()/2,getHeight()/2);
paintWatchBoard(canvas); //畫表盤
paintScale(canvas); //畫刻度
paintPoint(canvas); //畫指針
canvas.drawCircle(0,0,15,mSecondPaint); //爲了美觀,也讓錶盤更接近我們顯示生活中的樣子,我在圓盤中心畫了一個大紅圓點裝飾秒針
postInvalidateDelayed(1000); //每隔一秒鐘畫一次
}
/**
* 畫表盤
* @param canvas
*/
private void paintWatchBoard(Canvas canvas){
initPaint();
canvas.save();
canvas.drawCircle(0,0,mWatchRadius,mPaint); //畫圓盤
canvas.restore();
}
/**
* 初始化畫筆
*/
private void initPaint(){
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
}
/**
* 畫刻度及整點數字
* @param canvas
*/
private void paintScale(Canvas canvas){
int lineLength; //刻度線長度
canvas.save();
for (int i = 0;i<60;i++){
if (i%5 == 0){//整點刻度下畫筆相關屬性
mPaint.setStrokeWidth(dp2px(getContext(),1.5f));
mPaint.setColor(mHourScaleColor);
lineLength = dp2px(getContext(),8);
canvas.drawLine(0,-mWatchRadius+mWatchScalePadding,0,-mWatchRadius+mWatchScalePadding+lineLength,mPaint);
mPaint.setColor(mTimeTextColor);
mPaint.setTextSize(mTimeTextSize);
canvas.drawText(mTimes[i/5],-mTimeTextSize/2,-mWatchRadius+mWatchScalePadding + lineLength+mTimeTextSize,mPaint);//整點的位置標上整點時間數字
}else {//非整點刻度下畫筆相關屬性
mPaint.setStrokeWidth(dp2px(getContext(),0.8f));
mPaint.setColor(mWatchScaleColor);
lineLength = dp2px(getContext(),5);
canvas.drawLine(0,-mWatchRadius+mWatchScalePadding,0,-mWatchRadius+mWatchScalePadding+lineLength,mPaint);
}
canvas.rotate(6);//每次畫完一個刻度線,畫筆順時針旋轉6度(360/60,相鄰兩刻度之間的角度差爲6度)
}
canvas.restore();
}
/**
* 初始化指針
*/
private void initPointPaint(){
mHourPaint = new Paint();
mHourPaint.setAntiAlias(true);
mHourPaint.setStyle(Paint.Style.FILL);
mHourPaint.setStrokeWidth(16);
mHourPaint.setColor(mHourPointColor);
mMinutePaint = new Paint();
mMinutePaint.set(mHourPaint);
mMinutePaint.setStrokeWidth(12);
mMinutePaint.setColor(mMinutePointColor);
mSecondPaint = new Paint();
mSecondPaint.set(mHourPaint);
mSecondPaint.setStrokeWidth(7);
mSecondPaint.setColor(mSecondPointColor);
mEndPointLength = mWatchRadius/6; //(修飾部分)指針尾部長度,定義爲錶盤半徑的六分之一
}
/**
* 畫指針
* @param canvas
*/
private void paintPoint(Canvas canvas){
initPointPaint();
Calendar c = Calendar.getInstance(); //取當前時間
float hour = c.get(Calendar.HOUR_OF_DAY);
float minute = c.get(Calendar.MINUTE);
float second = c.get(Calendar.SECOND);
//繪製時針
canvas.save();
canvas.rotate((hour+minute/60)*30);
canvas.drawLine(0,0,0,-mHourPointLength,mHourPaint);
canvas.drawLine(0,0,0,mEndPointLength,mHourPaint);
canvas.restore();
//繪製分針
canvas.save();
canvas.rotate((minute+second/60)*6);
canvas.drawLine(0,0,0,-mMinutePointLength,mMinutePaint);
canvas.drawLine(0,0,0,mEndPointLength,mMinutePaint);
canvas.restore();
//繪製秒針
canvas.save();
canvas.rotate(second*6);
canvas.drawLine(0,0,0,-mSecondPointLength,mSecondPaint);
canvas.drawLine(0,0,0,mEndPointLength,mSecondPaint);
canvas.restore();
}
/**
* dp轉px
*/
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
使用如下
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.csun.nusing.myview.WatchView
android:id="@+id/watchview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:timeTextSize="20dp"
app:watchRadius="150dp"
app:hourPointLength="80dp"
app:minutePointLength="100dp"
app:secondPointLength="115dp"/>
</RelativeLayout>