写点什么

安卓开发教你如何自定义 View 并实现炫酷进度条

用户头像
Android架构
关注
发布于: 17 小时前

下面介绍该圆形进度条的具体实现(按上面的 4 个步骤)




1.定义 attr.xml 文件,这是个属性文件,定义了圆形进度条的各种属性,你也可以根据实际情况自行增加或减少属性,下面的 innerBackground 定义了圆形内部的背景颜色,outerBackground 定义了圆形进度条边框的颜色,roundWidth 定义了半径,progressTextSize 和 progressTextColor 则分别定义了进度条内的文字大小颜色


<?xml version="1.0" encoding="utf-8"?>


<resources>


<declare-styleable name="CircleProgressBar">


<attr name="innerBackground" format="color" />


<attr name="outerBackground" format="color" />


<attr name="roundWidth" format="dimension" />


<attr name="progressTextSize" format="dimension" />


<attr name="progressTextColor" format="color" />


</declare-styleable>


</resources>


2.在构造方法中获取 attr.xml 中定义的属性,这一步很关键,而且要注意,由于属性文件与自定义控件的类是绑定的,而且安卓系统规定了获取并设置控件属性的值时,要用“R.styleable.类名_属性名”来获取并设置该属性,具体见代码及注释


public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {


super(context, attrs, defStyleAttr);


// 获取 attr.xml 文件中的属性


TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);


// 注意,获取 innerBackground 属性不是 R.styleable.innerBackground,而是 R.styleable.CicleProgressBar_innerBackground


mInnerBackground = array.getColor(R.styleable.CircleProgressBar_innerBackground, mInnerBackground);


mOuterBackground = array.getColor(R.styleable.CircleProgressBar_outerBackground, mOuterBackground);


mRoundWidth = (int) array.getDimension(R.styleable.CircleProgressBar_roundWidth, dip2px(10));


mProgressTextSize = array.getDimensionPixelSize(R.styleable.CircleProgressBar_progressTextSize,


sp2px(mProgressTextSize));


mProgressTextColor = array.getColor(R.styleable.CircleProgressBar_progressTextColor, mProgressTextColor);


array.recycle();


mInnerPaint = new Paint();


mInnerPaint.setAntiAlias(true);


mInnerPaint.setColor(mInnerBackground);


mInnerPaint.setStrokeWidth(mRoundWidth);


mInnerPaint.setStyle(Paint.Style.STROKE);


mOuterPaint = new Paint();


mOuterPaint.setAntiAlias(true);


mOuterPaint.setColor(mOuterBackground);


mOuterPaint.setStrokeWidth(mRoundWidth);


mOuterPaint.setStyle(Paint.Style.STROKE);


mTextPaint = new Paint();


mTextPaint.setAntiAlias(true);


mTextPaint.setColor(mProgressTextColor);


mTextPaint.setTextSize(mProgressTextSize);


}


3.重写 onMesure() 和 onDraw()方法,这两个方法可以设置自定义的属性和可以自己用 canvas 对象去画自定义的控件,进而实现漂亮的外观效果


@Override


protected void onMeasure(int widthMeasureSpec, int heightMeas


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ureSpec) {


super.onMeasure(widthMeasureSpec, heightMeasureSpec);


int width = MeasureSpec.getSize(widthMeasureSpec);


int height = MeasureSpec.getSize(heightMeasureSpec);


setMeasuredDimension(Math.min(width, height), Math.min(width, height));


}


@Override


protected void onDraw(Canvas canvas) {


// 先画内圆


int width = getWidth()/2;


int radius = width;


canvas.drawCircle(radius,radius,radius-mRoundWidth/2,mInnerPaint);


//画圆弧


@SuppressLint("DrawAllocation")


RectF rectF=new RectF(mRoundWidth/2,mRoundWidth/2, getWidth()-mRoundWidth/2,getHeight()-mRoundWidth/2);


//如果进度为 0 就不绘制


if (mProgress == 0) {


return;


}


float percent=(float)mProgress/mMax;


canvas.drawArc(rectF,0,360*percent,false,mOuterPaint);


// 画进度文字


String text = ((int) (percent * 100)) + "%";


@SuppressLint("DrawAllocation")


Rect rect=new Rect();


mTextPaint.getTextBounds(text,0,text.length(),rect);


float dx=getWidth()/2-rect.width()/2;


@SuppressLint("DrawAllocation")


Paint.FontMetricsInt fontMetricsInt=new Paint.FontMetricsInt();


int dy=(fontMetricsInt.bottom - fontMetricsInt.top)/2-fontMetricsInt.bottom;


float baseLine=getHeight()/2+dy;


canvas.drawText(text,dx,baseLine,mTextPaint);


}


4.在 main_activity.xml 布局文件中使用自定义的控件 CircleProgressBar,自定义控件的使用和安卓系统原生自带的控件使用方法是一样的,但是要注意,由于是自定义的,如果你使用控件直接用类名是不行的,安卓系统不能自动识别,这时你可以自己引入名称空间或者在标签上写全限定类名,这里采用的是第二种,并且可以在下面设置你已经定义好的属性值


<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"


xmlns:app="http://schemas.android.com/apk/res-auto"


xmlns:tools="http://schemas.android.com/tools"


android:layout_width="match_parent"


android:layout_height="match_parent"


android:orientation="vertical"


tools:context=".MainActivity">


<com.my.myview.CircleProgressBar

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
安卓开发教你如何自定义View并实现炫酷进度条