Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之自定義View以及畫一個時鐘

Android之自定義View以及畫一個時鐘

編輯:關於Android編程

概述:

當Android自帶的View滿足不了開發者時,自定義View就發揮了很好的作用。
建立一個自定義View,需要繼承於View類,並且實現其中的至少一個構造函數和兩個方法:onMeasure()和onDraw();
onMeasure()用於設置自定義View的尺寸,onDraw()用於繪制View中的內容。

在onDraw()方法中,需要調用畫筆繪制圖形或文本,繪制的模板時Canvas對象, Canvas類中用來繪制圖形文本的方法有:

drawRect(RectF rect, Paint paint) //繪制區域,參數一為RectF一個區域

drawPath(Path path, Paint paint) //繪制一個路徑,參數一為Path路徑對象

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //貼圖,參數一就是我們常規的Bitmap對象,參數二是源區域(這裡是bitmap),參數三是目標區域(應該在canvas的位置和大小),參數四是Paint畫刷對象,因為用到了縮放和拉伸的可能,當原始Rect不等於目標Rect時性能將會有大幅損失。

drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) //畫線,參數一起始點的x軸位置,參數二起始點的y軸位置,參數三終點的x軸水平位置,參數四y軸垂直位置,最後一個參數為Paint 畫刷對象。

drawPoint(float x, float y, Paint paint) //畫點,參數一水平x軸,參數二垂直y軸,第三個參數為Paint對象。

drawText(String text, float x, floaty, Paint paint) //渲染文本,Canvas類除了上面的還可以描繪文字,參數一是String類型的文本,參數二x軸,參數三y軸,參數四是Paint對象。

drawOval(RectF oval, Paint paint)//畫橢圓,參數一是掃描區域,參數二為paint對象;

drawCircle(float cx, float cy, float radius,Paint paint)// 繪制圓,參數一是中心點的x軸,參數二是中心點的y軸,參數三是半徑,參數四是paint對象;

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//畫弧,參數一是RectF對象,一個矩形區域橢圓形的界限用於定義在形狀、大小、電弧,參數二是起始角(度)在電弧的開始,參數三掃描角(度)開始順時針測量的,參數四是如果這是真的話,包括橢圓中心的電弧,並關閉它,如果它是假這將是一個弧線,參數五是Paint對象。

繪制圖形需要畫筆Paint對象,Paint類中的方法有:

setARGB(int a, int r, int g, int b) // 設置 Paint對象顏色,參數一為alpha透明值

setAlpha(int a) // 設置alpha不透明度,范圍為0~255

setAntiAlias(boolean aa) // 是否抗鋸齒

setColor(int color) // 設置顏色,這裡Android內部定義的有Color類包含了一些常見顏色定義

setTextScaleX(float scaleX) // 設置文本縮放倍數,1.0f為原始

setTextSize(float textSize) // 設置字體大小

setUnderlineText(booleanunderlineText) // 設置下劃線

Demo

一個自定義時鐘視圖的寫法:

public class MyView extends View {

    private int width;
    private int height;
    private Paint mPaintLine;
    private Paint mPaintCircle;
    private Paint mPaintHour;
    private Paint mPaintMinute;
    private Paint mPaintSec;
    private Paint mPaintText;
    private Calendar mCalendar;
    public static final int NEED_INVALIDATE = 0X23;

    //每隔一秒,在handler中調用一次重新繪制方法
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what){
                case NEED_INVALIDATE:
                    mCalendar = Calendar.getInstance();
                    invalidate();//告訴UI主線程重新繪制
                    handler.sendEmptyMessageDelayed(NEED_INVALIDATE,1000);
                    break;
                default:
                    break;
            }
        }
    };

    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mCalendar = Calendar.getInstance();

        mPaintLine = new Paint();
        mPaintLine.setColor(Color.BLUE);
        mPaintLine.setStrokeWidth(10);

        mPaintCircle = new Paint();
        mPaintCircle.setColor(Color.GREEN);//設置顏色
        mPaintCircle.setStrokeWidth(10);//設置線寬
        mPaintCircle.setAntiAlias(true);//設置是否抗鋸齒
        mPaintCircle.setStyle(Paint.Style.STROKE);//設置繪制風格

        mPaintText = new Paint();
        mPaintText.setColor(Color.BLUE);
        mPaintText.setStrokeWidth(10);
        mPaintText.setTextAlign(Paint.Align.CENTER);
        mPaintText.setTextSize(40);

        mPaintHour = new Paint();
        mPaintHour.setStrokeWidth(20);
        mPaintHour.setColor(Color.BLUE);

        mPaintMinute = new Paint();
        mPaintMinute.setStrokeWidth(15);
        mPaintMinute.setColor(Color.BLUE);

        mPaintSec = new Paint();
        mPaintSec.setStrokeWidth(10);
        mPaintSec.setColor(Color.BLUE);

        handler.sendEmptyMessage(NEED_INVALIDATE);//向handler發送一個消息,讓它開啟重繪
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int circleRadius = 400;
        //畫出大圓
        canvas.drawCircle(width / 2, height / 2, circleRadius, mPaintCircle);
        //畫出圓中心
        canvas.drawCircle(width / 2, height / 2, 20, mPaintCircle);
        //依次旋轉畫布,畫出每個刻度和對應數字
        for (int i = 1; i <= 12; i++) {
            canvas.save();//保存當前畫布
            canvas.rotate(360/12*i,width/2,height/2);
            //左起:起始位置x坐標,起始位置y坐標,終止位置x坐標,終止位置y坐標,畫筆(一個Paint對象)
            canvas.drawLine(width / 2, height / 2 - circleRadius, width / 2, height / 2 - circleRadius + 30, mPaintCircle);
            //左起:文本內容,起始位置x坐標,起始位置y坐標,畫筆
            canvas.drawText(+i, width / 2, height / 2 - circleRadius + 70, mPaintText);
            canvas.restore();//
        }

        int minute = mCalendar.get(Calendar.MINUTE);//得到當前分鐘數
        int hour = mCalendar.get(Calendar.HOUR);//得到當前小時數
        int sec = mCalendar.get(Calendar.SECOND);//得到當前秒數

        float minuteDegree = minute/60f*360;//得到分針旋轉的角度
        canvas.save();
        canvas.rotate(minuteDegree, width / 2, height / 2);
        canvas.drawLine(width / 2, height / 2 - 250, width / 2, height / 2 + 40, mPaintMinute);
        canvas.restore();

        float hourDegree = (hour*60+minute)/12f/60*360;//得到時鐘旋轉的角度
        canvas.save();
        canvas.rotate(hourDegree, width / 2, height / 2);
        canvas.drawLine(width / 2, height / 2 - 200, width / 2, height / 2 + 30, mPaintHour);
        canvas.restore();

        float secDegree = sec/60f*360;//得到秒針旋轉的角度
        canvas.save();
        canvas.rotate(secDegree,width/2,height/2);
        canvas.drawLine(width/2,height/2-300,width/2,height/2+40,mPaintSec);
        canvas.restore();

    }
}

需要在布局中加載自定義View,名字必須是全名(包括包名):
activity_timer



    

主活動setContentView就行了

public class TimerActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_timer);
    }
}

演示結果:
這裡寫圖片描述

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved