日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android 自定义view控件,Android 自定义View——自定义View控件

發(fā)布時間:2024/9/27 Android 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android 自定义view控件,Android 自定义View——自定义View控件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Android給我們提供了大量的View控件,但這還是遠遠滿足不了我們的要求,有時候開發(fā)所需要的控件形式是在Android提供的控件中是不存在,這就需要我們自己去定義一個。那么如何自定義控件?

學(xué)習(xí)自定義控件,首先要先掌握Canvas類的使用。

Canvas

Canvas, 我們稱之為“畫布“,主要適用于繪制View的。

Canvas中提供了大量繪制圖形的方法:

繪制扇形:

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint):

第一個參數(shù)RectF對象,指定扇形的區(qū)域;第二個參數(shù)是起始角度;第三個參數(shù)是旋轉(zhuǎn)角度,順時針旋轉(zhuǎn);第四個參數(shù)是是否填充,true為填充,false為不填充,也就是為一條弧線;第五個參數(shù)是繪制圖形的畫筆對象Paint。

RectF:

通過RectF(float left, float top, float right, float bottom)構(gòu)造器創(chuàng)建RectF對象,我們通過下圖理解各個參數(shù)的含義,RectF對象指代的就是一個矩形區(qū)域。我們通過這四個參數(shù)構(gòu)建矩形區(qū)域。

Paint:

是繪制所有圖形所用到的一個畫筆,我們在稍后講解。

drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

這個是將扇形區(qū)域左,上,右,下邊的坐標直接輸入,而不是通過RectF對象。其他參數(shù)同上。

繪制圓形:

drawCircle(float cx, float cy, float radius, Paint paint)

第一、二個參數(shù)是指圓形的x, y坐標; 第三個參數(shù)是半徑; 第四個參數(shù)是畫筆Paint對象。

繪制直線:

drawLine(float startX, float startY, float stopX, float stopY, Paint paint)

兩點確定一條直線,第一、二參數(shù)是起始點的坐標;第三、四參數(shù)是結(jié)束點的坐標;第五個參數(shù)畫筆Paint對象。

drawLines(float[] pts, Paint paint)

多個點確定一條直線,第一個參數(shù)是點的數(shù)組;第二個參數(shù)是畫筆Paint對象。

drawLines(float[] pts, int offset, int count, Paint paint)

繪制橢圓:

drawOval(float left, float top, float right, float bottom, Paint paint)

前四個參數(shù)是橢圓的左,上,右,下邊的坐標,第五個是畫筆Paint對象。

drawOval(RectF oval, Paint paint)

第一個參數(shù)是RectF對象, 第二個參數(shù)是畫筆Paint對象。

繪制矩形:

drawRect(RectF rect, Paint paint)

第一個參數(shù)是RectF對象, 第二個參數(shù)是畫筆Paint對象。

繪制點:

drawPoint(float x, float y, Paint paint)

第一、二個參數(shù)點的坐標,第三個參數(shù)為Paint對象。

渲染文本:

drawText(String text, float x, floaty, Paint paint)

drawText(CharSequence text, int start, int end, float x, float y, Paint paint)

drawText(char[] text, int index, int count, float x, float y, Paint paint)

drawText(String text, int start, int end, float x, float y, Paint paint)

Canvas中還給我們提供了很多繪制其他圖形的方法,這里我們不在一一列舉。我們來看一下Paint”畫筆“。

Paint

Paint是用于繪制的畫筆,Canvas就像是我們的畫紙,我們需要筆才可以完成一整幅圖。Paint中為我們提供了很多設(shè)置的方法(我們這里只列舉常用的方法):

setARGB(int a, int r, int g, int b)

設(shè)置 Paint對象顏色,參數(shù)一為alpha透明值

setAlpha(int a)

設(shè)置alpha不透明度,范圍為0~255

setAntiAlias(boolean aa)

是否抗鋸齒,這個一般是都要設(shè)置的。

setColor(int color)

設(shè)置顏色,這里Android內(nèi)部定義的有Color類包含了一些常見顏色定義

setTextScaleX(float scaleX)

設(shè)置文本縮放倍數(shù),1.0f為原始

setTextSize(float textSize)

設(shè)置字體大小

setUnderlineText(booleanunderlineText)

設(shè)置下劃線

setStrokeCap(Paint.Cap cap)

當畫筆樣式為STROKE或FILL_OR_STROKE時,設(shè)置筆刷的圖形樣式,如圓形樣式 Cap.ROUND,或方形樣式Cap.SQUARE

setSrokeJoin(Paint.Join join)

設(shè)置繪制時各圖形的結(jié)合方式,如平滑效果等

自定義View

現(xiàn)在我們來使用Canvas類自定義一個View控件。自定義控件步驟如下:

1. 自定義View,首先定義一個MyView類繼承View類。

2. 重寫View的兩個構(gòu)造器。

View是包含四個構(gòu)造器的,我們必須重寫MyWidgetView(Context context, AttributeSet attrs)構(gòu)造器,因為該構(gòu)造器的第二個參數(shù)是與xml布局文件相聯(lián)系的,如果沒有重寫該構(gòu)造器,將不能在布局中使用該控件。這里我們重寫他的兩個構(gòu)造器:

public MyView(Context context) {

super(context);

}

public MyView(Context context, AttributeSet attrs) {

super(context, attrs);

}

3. 重寫onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法,定義控件的尺寸:寬度和高度。在布局中使用該控件時會會傳入控件的尺寸,只有當傳入尺寸之后且調(diào)用onMesure之后,控件才會有寬度和高度。

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);

height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);

setMeasuredDimension(width, height);//設(shè)置寬和高

}

重寫onDraw(Canvas canvas)方法,我們在該方法中定義繪制View,當我們在Activity或其他地方使該控件時, UI主線程會調(diào)用onDraw方法繪制。

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

}

onDraw(Canvas canvas)方法中傳入了一個Canvas對象,我們在定義控件時,使用Canvas繪制。

繪制時鐘

這里我們通過繪制一個時鐘來鞏固一下自定義控件以及Canvas類的使用。

1. 定義一個MyView繼承View。

2. 重寫MyView(Context context, AttributeSet attrs)構(gòu)造器。

3. 在重寫onMeasureh和onDraw方法。

4. 在onDraw方法中繪制。

大體步驟就是這樣,我們先貼代碼,逐步講解:

public class MyView extends View {

private int width;//設(shè)置高

private int height;//設(shè)置高

private Paint mPaintLine;//定義一個繪制直線的畫筆

private Paint mPaintSecondLine;//定義一個繪制直線的畫筆

private Paint mPaintInterCircle;//定義一個繪制圓的畫筆

private Paint mPaintOutSideCircle;//定義一個繪制圓的畫筆

private Paint mPaintText;//定義一個繪制文字的畫筆

private Calendar mCalendar;//創(chuàng)建一個時間類

private static final int NEED_INVALIDATE=0X6666;

//操作UI主線程

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

switch (msg.what){

case NEED_INVALIDATE:

//跟新時間

mCalendar=Calendar.getInstance();

invalidate();

sendEmptyMessageDelayed(NEED_INVALIDATE,1000);

break;

}

}

};

public MyView(Context context) {

super(context);

}

public MyView(Context context, AttributeSet attrs) {

super(context, attrs);

//初始化畫直線的畫筆

mPaintLine = new Paint();

mPaintLine.setAntiAlias(true);//消除鋸齒

mPaintLine.setColor(Color.GRAY);//設(shè)置畫筆顏色

mPaintLine.setStyle(Paint.Style.STROKE);//設(shè)置為空心

mPaintLine.setStrokeWidth(10);//設(shè)置寬度

// 初始化秒針的畫筆

mPaintSecondLine = new Paint();

mPaintSecondLine.setAntiAlias(true);//消除鋸齒

mPaintSecondLine.setColor(Color.GRAY);//設(shè)置畫筆顏色

mPaintSecondLine.setStyle(Paint.Style.STROKE);//設(shè)置為空心

mPaintSecondLine.setStrokeWidth(7);//設(shè)置寬度

//初始化內(nèi)圓的畫筆

mPaintInterCircle = new Paint();

mPaintInterCircle.setAntiAlias(true);//消除鋸齒

mPaintInterCircle.setColor(Color.BLACK);

mPaintInterCircle.setStyle(Paint.Style.STROKE);//設(shè)置為空心

mPaintInterCircle.setStrokeWidth(5);

//初始化外圓的畫筆

mPaintOutSideCircle = new Paint();

mPaintOutSideCircle.setAntiAlias(true);//消除鋸齒

mPaintOutSideCircle.setColor(Color.BLACK);

mPaintOutSideCircle.setStyle(Paint.Style.STROKE);//設(shè)置為空心

mPaintOutSideCircle.setStrokeWidth(10);

//繪制文字的畫筆

mPaintText = new Paint();

mPaintText.setAntiAlias(true);//消除鋸齒

mPaintText.setColor(Color.GRAY);

mPaintText.setStyle(Paint.Style.STROKE);//設(shè)置為空心

mPaintText.setTextAlign(Paint.Align.CENTER);

mPaintText.setTextSize(40);

mPaintText.setStrokeWidth(6);

//初始化日歷

mCalendar = Calendar.getInstance();

//發(fā)送一個消息給UI主線程

handler.sendEmptyMessageDelayed(NEED_INVALIDATE,2000);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);

height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);

setMeasuredDimension(width, height);//設(shè)置寬和高

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

// 主線程自動調(diào)用

canvas.drawCircle(width / 2, height / 2, 300, mPaintInterCircle);

canvas.drawCircle(width / 2, height / 2, 320, mPaintOutSideCircle);

for(int i=1; i<=12;i++){

canvas.save();//保存當前狀態(tài)

canvas.rotate(360 / 12 * i, width / 2, height / 2);

canvas.drawLine(width / 2, height / 2 - 300, width / 2, height / 2 - 270, mPaintLine);

canvas.drawText("" + i, width / 2, height / 2 - 240, mPaintText);

canvas.restore();//回到save()方法保存的狀態(tài)

}

//繪制分針

int minute= mCalendar.get(Calendar.MINUTE);

float minuteDegree = minute/60f*360;

canvas.save();

canvas.rotate(minuteDegree, width / 2, height / 2);

canvas.drawLine(width / 2, height / 2 - 200, width / 2, height / 2 + 40, mPaintLine);

canvas.restore();

//繪制時針

int hour= mCalendar.get(Calendar.HOUR);

float hourDegree = (hour*60+minute)//(12f*60)*360;

canvas.save();

canvas.rotate(hourDegree, width / 2, height / 2);

canvas.drawLine(width / 2, height / 2 - 170, width / 2, height / 2 + 30, mPaintLine);

canvas.restore();

//繪制秒針

int second = mCalendar.get(Calendar.SECOND);

float secondDegree = second*6;//一秒是6度。

canvas.save();

canvas.rotate(secondDegree, width / 2, height / 2);

canvas.drawLine(width / 2, height / 2 - 220, width / 2, height / 2 + 50, mPaintSecondLine);

canvas.restore();

}

}

繪制兩個圓形嵌套這個很簡單,不用多說。然后繪制刻度,是使用了Canvas畫布的旋轉(zhuǎn),這個很好理解,我們在畫畫的時候,有時候要畫一些比較難的角度,我們都是將畫板旋轉(zhuǎn)而不是我們自己換角度。在繪制時鐘時,我們要繪制時鐘每個時間的刻度,我們可以將要繪制刻度的位置旋轉(zhuǎn)到豎直方向,然后繪制。

for(int i=1; i<=12;i++){

canvas.save();//保存當前狀態(tài)

canvas.rotate(360 / 12 * i, width / 2, height / 2);

canvas.drawLine(width / 2, height / 2 - 300, width / 2, height / 2 - 270, mPaintLine);

canvas.drawText("" + i, width / 2, height / 2 - 240, mPaintText);

canvas.restore();//回到save()方法保存的狀態(tài)

}

然后繪制時針,分針和秒針,他們都是繪制一條線。然后通過獲取當前的時間將這條線指向?qū)Φ脮r間點,也就是偏轉(zhuǎn)對得角度。這里的偏轉(zhuǎn)我們依然使用畫布的偏轉(zhuǎn)。

以上完成后,我們的時鐘就差不多完成了,但是,我們發(fā)現(xiàn)我們的表并沒有走。實現(xiàn)我們繪制的時鐘轉(zhuǎn)動的方式就是然我們的時鐘每一秒onDraw一次,這樣我們的時鐘正常了。onDraw是UI主線程不斷調(diào)用重繪界面的,因此我們需要使用到Handler,通過發(fā)送一個消息給Handler對象,讓Handler對象在每一秒重繪一次MyView控件。這里重繪不能調(diào)用onDraw()方法額,而要調(diào)用的是invalidate()方法,invalidate()方法中調(diào)用了onDraw()方法。

//操作UI主線程

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

switch (msg.what){

case NEED_INVALIDATE:

//跟新時間

mCalendar=Calendar.getInstance();

invalidate();

sendEmptyMessageDelayed(NEED_INVALIDATE,1000);

break;

}

}

};

這樣我們的時鐘也轉(zhuǎn)動了……

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的android 自定义view控件,Android 自定义View——自定义View控件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。