Android之自訂View以及畫一個時鐘

來源:互聯網
上載者:User

Android之自訂View以及畫一個時鐘
概述:

當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);    }}

示範結果:

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.