Android 自定義view(畫表盤)

自定義View就是繼承一個View的子孫類或View類,然後重寫其中的一些方法來完成界面的美觀效果。
效果:
這裏寫圖片描述

佈局:

    <so.wih.android.myview.MyLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

代碼:

public class MyLayout extends View {

    private int mWidth;
    private int mHeight;
    private Paint mCirclePaint;
    private int circleRadius ;
    private Paint mPaintLine;
    private Paint mPaintText;
    private Calendar mCalendar;
    public static final int what_update = 100;

    public Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case what_update :
                    mCalendar=Calendar.getInstance();//這一句必須有,如果沒有就不刷新時間
                    invalidate();//重繪界面 會調用onDraw方法
                    handler.sendEmptyMessageDelayed(what_update,1000);
                    break;
            }
        }
    };

    public MyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyLayout(Context context) {
        super(context);
        init();
    }

    /**
     * 初始化控件
     */
    private void init() {
        //圓半徑
        circleRadius =  300 ;
        //畫圓的畫筆
        mCirclePaint = new Paint();
        mCirclePaint.setColor(Color.GREEN);
        mCirclePaint.setStrokeWidth(10);//設置繪製的筆畫寬度
        mCirclePaint.setStyle(Paint.Style.STROKE); //空心

        //畫刻度的畫筆
        mPaintLine = new Paint();
        mPaintLine.setColor(Color.RED);
        mPaintLine.setStrokeWidth(10);

        //畫數字的畫筆
        mPaintText = new Paint();
        mPaintText.setColor(Color.GRAY);
        mPaintText.setTextSize(35);
        mPaintText.setStrokeWidth(10);
        mPaintText.setTextAlign(Paint.Align.CENTER); //文字居中

        //發送消息
        handler.sendEmptyMessage(what_update);
        //獲取時間
        mCalendar = Calendar.getInstance();
    }

    /*
     * 當一個view 從創建對象,到顯示在屏幕中,的幾個重要步驟:
     *
     * 1- 測量控件大小
     *      onMeasure
     * 2- 指定控件位置
     *      onLayout
     * 3- 繪製控件的內容
     *      onDraw
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 我們要做的就是設置測量大小,即,view想要的大小
        mWidth = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        mHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 繪製大圓
        canvas.drawCircle(mWidth/2, mHeight/2, circleRadius, mCirclePaint);
        //小圓
        canvas.drawCircle(mWidth / 2, mHeight / 2, 5, mCirclePaint);

        //繪製刻度
        for (int i = 1; i <=12 ; i++) {
            //大刻度
            canvas.save(); //保存當前矩陣並將其存儲到私有堆棧上
            float degrees = 360/12*i ;
            canvas.rotate(degrees,mWidth/2, mHeight/2);
            canvas.drawLine(mWidth / 2 ,(mHeight / 2-circleRadius) ,
                    mWidth / 2 ,(mHeight / 2-circleRadius+20) ,mPaintLine);
            canvas.drawText(""+i,mWidth/2,(mHeight / 2-circleRadius+50),mPaintText);
            /**
             * 這個調用是爲了平衡save(),用於移除自上次保存時的矩陣/剪輯狀態的所有修改。
             * 不能比svae()調用的次數多
             */
            canvas.restore();

            //小刻度
            canvas.save(); //保存當前矩陣並將其存儲到私有堆棧上
            float degrees2 = 360/12*(i-1)+15 ;
            canvas.rotate(degrees2,mWidth/2, mHeight/2);
            canvas.drawLine(mWidth / 2 ,(mHeight / 2-circleRadius) ,
                    mWidth / 2 ,(mHeight / 2-circleRadius+10) ,mPaintLine);
//            canvas.drawText(""+i,mWidth/2,(mHeight / 2-circleRadius+50),mPaintText);
            /**
             * 這個調用是爲了平衡save(),用於移除自上次保存時的矩陣/剪輯狀態的所有修改。
             * 不能比svae()調用的次數多
             */
            canvas.restore();
        }

        //繪製時針、分針和秒針
        int hour = mCalendar.get(Calendar.HOUR);
        int minute = mCalendar.get(Calendar.MINUTE);
        int second = mCalendar.get(Calendar.SECOND);
        //小時的角度
        float hourDegree = 360 / 12f * hour ;
        canvas.save();//這個方法和restore配合用於錶盤歸位
        canvas.rotate(hourDegree, mWidth / 2, mHeight / 2);//以錶盤中心爲中心旋轉現在分鐘數*(360度/60分)
        canvas.drawLine(mWidth / 2 ,mHeight / 2 , mWidth / 2 ,(mHeight / 2 - circleRadius+200) ,mPaintLine);
        canvas.restore();//錶盤歸於原位
        //分鐘的角度
        float minuteDegree = 360 / 60f * minute ;
        canvas.save();//這個方法和restore配合用於錶盤歸位
        canvas.rotate(minuteDegree, mWidth / 2, mHeight / 2);//以錶盤中心爲中心旋轉現在分鐘數*(360度/60分)
        canvas.drawLine(mWidth / 2 ,mHeight / 2 , mWidth / 2 ,(mHeight / 2 - circleRadius+150) ,mPaintLine);
        canvas.restore();//錶盤歸於原位
        //秒針的角度
        float sedondDegree = 360 /60f * second ;
        canvas.save();//這個方法和restore配合用於錶盤歸位
        canvas.rotate(sedondDegree, mWidth / 2, mHeight / 2);//以錶盤中心爲中心旋轉現在分鐘數*(360度/60分)
        canvas.drawLine(mWidth / 2 ,mHeight / 2 , mWidth / 2 ,(mHeight / 2 - circleRadius+100) ,mPaintLine);
        canvas.restore();//錶盤歸於原位


    }

}

參考自:http://blog.csdn.net/litao660044/article/details/48500417
這個大神寫的自定義控件很詳細。

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