自定義錶盤View

使用自定義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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章