Android自定义View——矩形圆角扇形进度View
概述
最近的项目需求中,有一个显示下载进度的需求。大概是这样子的,一个圆角矩形ImageView作为背景图,以这个矩形的中心作为圆心,圆角矩形的外切圆上的某个点为起点,进度为矩形上某个点与起点的角度。位于进度范围内的圆角矩形部分为透明,其它部分为半透明遮罩。效果如下图所示(因为背景图片并不是规则矩形,所以效果有点差):
矩形圆角扇形进度View的需求
如上图,剩余进度是半透明遮罩,完成进度部分为透明,可以设置进度,圆角,半透明遮罩的颜色,还有一个起始角度。相对来说需求很简单,和iOS的app升级时桌面上的升级进度效果基本一致。完成这个需求,自然而然地想到了自定义View,自定义一个遮罩层View,覆盖在ImageView上就可以了。
矩形圆角扇形进度View
- 新建attrs.xml定义属性文件,并增加相应的属性;
<declare-styleable name="CircleProgress">
<attr name="circleProgress" format="integer"/> <!-- 进度0-100 -->
<attr name="startAngle" format="integer"/> <!-- 开始的角度0-360 -->
<attr name="circleCorner" format="dimension" /> <!-- 圆角 -->
<attr name="backgroundColor" format="color"/> <!-- 背景的颜色 -->
</declare-styleable>
- 继承View并绘制遮罩层,实现自定义View,代码如下:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.bottle.app.R;
/**
* 原理就是利用一个圆角矩形A,和一个扇形B,裁切一块区域(A-B),然后把颜色绘制在这块区域,
* 被裁掉区域的中心角度为进度。
* 难度就在于如何裁剪出这一块区域:
* 1. 圆角矩形背景A:取View 的 padding 范围内的View空间即可;
* 2. 进度扇形背景B:以View的中心为圆心,矩形对角线为直径,起始角度为起点a,
* 得到圆上起点,进度角度b,得到圆上第二点,然后画弧度得到扇形;
* 3. 取A-B得到背景,然后画一个矩形即可。
*/
public class CircleProgress extends View {
public static final int PI_RADIUS = 180; // pi弧度对应的角度
private int mProgress; // 进度,取值范围: 0-100
private int mCorner; // 圆角,如果是矩形,取一半的话可以是圆
private int mStartAngle; // 百分比进度的起始值,0-n,其中0度与x轴方向一致
private int mBackgroundColor