自定義View
- 畫一個實心圓
- 效果圖
- 創建attrs.xml檔案
- 初始化樣式屬性
- 支持Padding屬性
- 支持wrap_content屬性
- 布局檔案中的應用
- 畫一個帶外圓環的圓
- 效果圖
- 創建attrs.xml檔案
- 初始化樣式屬性
- 內圓與外圓環的繪制
- 布局檔案中的應用
- 畫一個外圓環可根據數值變動的圓
- 效果圖
- 創建attrs.xml檔案
- 初始化樣式屬性
- 繪制View
- 提供方法修改樣式
- 布局檔案中的應用
畫一個實心圓
效果圖

創建attrs.xml檔案
在value檔案夾下創建一個名為attrs.xml檔案,為圓設定一個背景顏色的屬性,代碼如下:
<declare-styleable name="CircleView_Solid">
<attr name="CircleColor_Solid" format="color"/>
</declare-styleable>
初始化樣式屬性
為圓設定顏色屬性,并設定抗鋸齒
private void InitAttrs(Context context , AttributeSet attrs){
TypedArray array = context.getTheme().obtainStyledAttributes( attrs,R.styleable.CircleView_Solid,0,0 );
mCircleBGColor = array.getColor( R.styleable.CircleView_Solid_CircleColor_Solid,0xFFFFFFFF );
}
private void InitVar(){
mCirclePaint = new Paint( );
mCirclePaint.setAntiAlias( true );
mCirclePaint.setColor( mCircleBGColor );
}
支持Padding屬性
由于直接繼承view,不再onDraw()中進行處理,是無法直接使用Padding屬性,代碼如下:
protected void onDraw(Canvas canvas) {
super.onDraw( canvas );
int PaddingLeft = getPaddingLeft();
int PaddingRight = getPaddingRight();
int PaddingTop = getPaddingTop();
int PaddingBottom = getPaddingBottom();
int Width = (getWidth() - (PaddingLeft+PaddingRight)) / 2 +PaddingLeft;
int Height = (getHeight() -(PaddingTop+PaddingBottom))/2+PaddingTop;
int Radius = Math.min( Width,Height )/2;
canvas.drawCircle( Width,Height,Radius,mCirclePaint );
}
支持wrap_content屬性
若不在onMeasure()對wrap_content進行處理,效果很可能達不到預期效果,如果控制元件使用wrap_content屬性,那么他的Measure specification mode就為At_Most,而它的寬高就等于specSize,這種情況下specSize是就相當于父容器當前剩余的大小,代碼如下:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure( widthMeasureSpec, heightMeasureSpec );
int Width = 500;
int Height = 500;
int WidthMode = MeasureSpec.getMode( widthMeasureSpec );
int WidthSize = MeasureSpec.getSize( widthMeasureSpec );
int HeightMode = MeasureSpec.getMode( heightMeasureSpec );
int HeightSize = MeasureSpec.getSize( heightMeasureSpec );
if (WidthMode == MeasureSpec.AT_MOST && HeightMode == MeasureSpec.AT_MOST){
setMeasuredDimension( Math.min( Width,HeightSize ),Math.min( Height ,HeightSize) );
} else if (WidthMode == MeasureSpec.AT_MOST) {
setMeasuredDimension( Math.min( Width,HeightSize ),HeightSize );
}else if (HeightMode == MeasureSpec.AT_MOST){
setMeasuredDimension( WidthSize,Math.min( Height ,HeightSize) );
}
}
布局檔案中的應用
<com.franzliszt.customcircleview.CircleView_Solid
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:CircleColor_Solid="@color/colorRed"
android:padding="10dp"/>
畫一個帶外圓環的圓
效果圖

創建attrs.xml檔案
<declare-styleable name="CircleView_Text">
<!-- 內圓顏色-->
<attr name="CircleColor" format="color"/>
<!-- 外圓環顏色-->
<attr name="RingColor" format="color"/>
<!-- 圓的半徑-->
<attr name="Radius" format="dimension"/>
<!-- 外圓環的寬度-->
<attr name="StrokeWidth" format="dimension"/>
</declare-styleable>
初始化樣式屬性
private void InitAttrs(Context context , AttributeSet attrs){
TypedArray array = context.getTheme().obtainStyledAttributes( attrs,R.styleable.CircleView_Text,0,0 );
CircleColor = array.getColor( R.styleable.CircleView_Text_CircleColor,0xFFFFFFFF );
RingColor = array.getColor( R.styleable.CircleView_Text_RingColor,0xFFFFFFFF );
mRadius = array.getDimension( R.styleable.CircleView_Text_Radius,80 );
mStrokeWidth = array.getDimension( R.styleable.CircleView_Text_StrokeWidth,10 );
mRingRadius = mRadius + mStrokeWidth / 2;
}
private void InitVar(){
//內圓
//設定顏色
CirclePaint.setColor( CircleColor );
//設定填充方式
CirclePaint.setStyle( Paint.Style.FILL );
//設定抗鋸齒
CirclePaint.setAntiAlias( true );
//外圓環
RingPaint.setColor( RingColor );
RingPaint.setStyle( Paint.Style.STROKE );
RingPaint.setAntiAlias( true );
RingPaint.setStrokeWidth( mStrokeWidth );
}
內圓與外圓環的繪制
protected void onDraw(Canvas canvas) {
super.onDraw( canvas );
mCenterX = getWidth()/2;
mCenterY = getHeight()/2;
canvas.drawCircle( mCenterX,mCenterY,mRadius,CirclePaint );
RectF rect = new RectF( );
rect.left = mCenterX - mRingRadius;
rect.right = 2 * mRingRadius + (mCenterX - mRingRadius);
rect.top = mCenterY - mRingRadius;
rect.bottom = 2 * mRingRadius + (mCenterY - mRingRadius);
canvas.drawArc( rect,0,360,false,RingPaint );
}
布局檔案中的應用
<com.franzliszt.customcircleview.CircleView
android:layout_width="100dp"
android:layout_height="100dp"
app:Radius="40dp"
app:StrokeWidth="10dp"
app:CircleColor="@color/colorBlack"
app:RingColor="@color/colorRed"/>
畫一個外圓環可根據數值變動的圓
效果圖

創建attrs.xml檔案
<declare-styleable name="CircleView_Progress">
<!-- 內圓顏色-->
<attr name="CircleProgressColor" format="color"/>
<!-- 外圓環顏色-->
<attr name="RingProgressColor" format="color"/>
<!-- 外圓環覆寫部分顏色-->
<attr name="RingBgProgressColor" format="color"/>
<!-- 文字顏色-->
<attr name="TextProgressColor" format="color"/>
<!-- 圓的半徑-->
<attr name="RadiusProgress" format="dimension"/>
<!-- 外圓環的寬度-->
<attr name="StrokeWidthProgress" format="dimension"/>
<attr name="CurrentProgress" format="float"/>
</declare-styleable>
初始化樣式屬性
private void InitAttrs(Context context , AttributeSet attrs){
TypedArray array = context.getTheme().obtainStyledAttributes( attrs,R.styleable.CircleView_Progress,0,0 );
CircleColor = array.getColor( R.styleable.CircleView_Progress_CircleProgressColor,0xFFFFFFFF );
RingColor = array.getColor( R.styleable.CircleView_Progress_RingProgressColor,0xFFFFFFFF );
RingBgColor = array.getColor( R.styleable.CircleView_Progress_RingBgProgressColor,0xFFFFFFFF );
TextColor = array.getColor( R.styleable.CircleView_Progress_TextProgressColor, 0xFFFFFFFF);
mRadius = array.getDimension( R.styleable.CircleView_Progress_RadiusProgress,80 );
mStrokeWidth = array.getDimension( R.styleable.CircleView_Progress_StrokeWidthProgress,10 );
mCurrentProgress = array.getFloat( R.styleable.CircleView_Progress_CurrentProgress,10 );
mRingRadius = mRadius + mStrokeWidth / 2;
}
private void InitVar(){
//內圓
//設定顏色
CirclePaint.setColor( CircleColor );
//設定填充方式
CirclePaint.setStyle( Paint.Style.FILL );
//設定抗鋸齒
CirclePaint.setAntiAlias( true );
//外圓環
RingPaint.setColor( RingColor );
RingPaint.setStyle( Paint.Style.STROKE );
RingPaint.setAntiAlias( true );
RingPaint.setStrokeWidth( mStrokeWidth );
//外圓環覆寫部分
RingBgPaint.setColor( RingBgColor );
RingBgPaint.setStyle( Paint.Style.STROKE );
RingBgPaint.setAntiAlias( true );
RingBgPaint.setStrokeWidth( mStrokeWidth );
//中間文字
TextPaint.setStyle( Paint.Style.FILL );
TextPaint.setAntiAlias( true );
TextPaint.setColor( TextColor );
TextPaint.setTextSize( mRadius/2 );
//文字的高度
Paint.FontMetrics fontMetrics = TextPaint.getFontMetrics();
mTextHeight = (int)Math.ceil( fontMetrics.descent - fontMetrics.ascent );
}
繪制View
protected void onDraw(Canvas canvas) {
super.onDraw( canvas );
mCenterX = getWidth()/2;
mCenterY = getHeight()/2;
canvas.drawCircle( mCenterX,mCenterY,mRadius,CirclePaint );
RectF rect = new RectF( );
rect.left = mCenterX - mRingRadius;
rect.right = 2 * mRingRadius + (mCenterX - mRingRadius);
rect.top = mCenterY - mRingRadius;
rect.bottom = 2 * mRingRadius + (mCenterY - mRingRadius);
canvas.drawArc( rect,0,360,false,RingPaint );
//當mCurrentProgress大于0時,外圓環覆寫部分顯示
if (mCurrentProgress > 0){
RectF rect_progress = new RectF( );
rect_progress.left = mCenterX - mRingRadius;
rect_progress.right = 2 * mRingRadius + (mCenterX - mRingRadius);
rect_progress.top = mCenterY - mRingRadius;
rect_progress.bottom = 2 * mRingRadius + (mCenterY - mRingRadius);
//例如外圓環數值為35,即35/100*360,獲得外圓環覆寫部分
canvas.drawArc( rect,-90,(float) (mCurrentProgress / mTotalProgress)*360,false,RingBgPaint );
}
//文字部分
String text = mCurrentProgress+"%";
//文字部分的寬度
mTextWidth = TextPaint.measureText( text,0,text.length() );
canvas.drawText( text,mCenterX - mTextWidth / 2, mCenterY + mTextHeight / 4,TextPaint );
}
提供方法修改樣式
public void setProgress(double progress){
mCurrentProgress = progress;
postInvalidate();
}
public void setRingBgColor(int Color){
RingBgColor = Color;
postInvalidate();
}
public void setTextColor(int Color){
TextColor = Color;
postInvalidate();
}
布局檔案中的應用
<com.franzliszt.customcircleview.CircleView_ProgressBar
android:id="@+id/Progress"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="50dp"
app:Radius="100dp"
app:StrokeWidth="10dp"
app:CircleColor="@color/colorWhite"
app:RingColor="@color/colorGrey"
app:RingProgressColor="@color/colorRed"
app:TextProgressColor="@color/colorPrimary"
app:CurrentProgress="59"
/>
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/299370.html
標籤:其他
