Android自定义view之圆形进度条

简介:
本节介绍自定义view-圆形进度条
思路:
根据前面介绍的自定义view内容可拓展得之;
1:新建类继承自View
2:添加自定义view属性
3:重写onDraw(Canvas canvas)
4:实现功能
下面上代码

1.自定义view代码:

public class CustomView extends View {
	//背景圆环颜色
	private int circleColor;
	//进度条颜色&字体颜色(为了美观,所以设计字体颜色和进度条颜色值一致)
	private int secondCircleColor;
	//进度条&背景圆环宽度
	private float stroke_width;
	//进度值
	private float progress;
	//总进度值,默认为100
	private float totalProgress;
	//字体大小
	private float textSize;
	//填充模式
	private int style_type;
	public CustomView(Context context) {
		super(context);
	}

	public CustomView(Context context, AttributeSet attrs) {
		super(context, attrs);
		TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.CustomView);
		circleColor=array.getColor(R.styleable.CustomView_circleColor, Color.BLACK);
		secondCircleColor=array.getColor(R.styleable.CustomView_secondCircleColor, Color.RED);
		stroke_width=array.getDimension(R.styleable.CustomView_stroke_width, 2);
		progress=array.getFloat(R.styleable.CustomView_progress, 0);
		totalProgress=array.getFloat(R.styleable.CustomView_totalProgress, 100);
		textSize=array.getDimension(R.styleable.CustomView_textSize, 16);
		style_type=array.getInt(R.styleable.CustomView_style_Type, 0);
	}

	public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}

	public void setCircleColor(int color){
		circleColor=color;
	}
	public int getCircleColor(){
		return circleColor;
	}

	public void setSecondCircleColor(int color){
		secondCircleColor=color;
	}
	public int getSecondColor(){
		return secondCircleColor;
	}
	public void setStrokeWidth(float width){
		stroke_width=width;
	}
	public float getStrokeWidth(){
		return stroke_width;
	}
	public void setProgress(float progress){
		this.progress=progress;
		postInvalidate();//刷新界面
	}
	public float getProgress(){
		return this.progress;
	}
	public void setTotalProgress(float totalProgress){
		this.totalProgress=totalProgress;
	}
	public float getTotalProgress(){
		return this.totalProgress;
	}
	public void setTextSize(float textSize){
		this.textSize=textSize;
	}
	public float getTextSize(){
		return this.textSize;
	}
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//第一进度圆
		final Paint paint_background=new Paint();
		paint_background.setAntiAlias(true);
		paint_background.setStrokeWidth(stroke_width);
		paint_background.setStyle(Style.STROKE);
		paint_background.setColor(circleColor);
		//第二进度圆
		final Paint paint_progress=new Paint();
		paint_progress.setAntiAlias(true);
		paint_progress.setStrokeWidth(stroke_width);
		if(style_type==0){
			paint_progress.setStyle(Style.STROKE);
		}else if(style_type==1){
			paint_progress.setStyle(Style.FILL_AND_STROKE);
		}
		paint_progress.setColor(secondCircleColor);
		//画text
		final Paint paint_text=new Paint();
		paint_text.setAntiAlias(true);
		if(style_type==0){
			paint_text.setColor(secondCircleColor);
		}else if(style_type==1){
			paint_text.setColor(circleColor);
		}
		paint_text.setTextSize(textSize);
		paint_text.setTextAlign(Align.CENTER);
		if(getWidth()!=getHeight()){
			throw new IllegalArgumentException("高度和宽度必须相等");//控制宽度和高度
		}else{
			RectF circle_background=new RectF();
			circle_background.left=getLeft()+stroke_width;
			circle_background.right=getRight()-stroke_width;
			circle_background.top=getTop()+stroke_width;
			circle_background.bottom=getBottom()-stroke_width;
			canvas.drawArc(circle_background, -90, 360, false, paint_background);
			RectF circle_progress=new RectF();
			circle_progress.left=getLeft()+stroke_width;
			circle_progress.right=getRight()-stroke_width;
			circle_progress.top=getTop()+stroke_width;
			circle_progress.bottom=getBottom()-stroke_width;
			if(progress>totalProgress){
				throw new IllegalArgumentException("当前进度值不能大于总进度值");
			}else{
				if(style_type==0){
					canvas.drawArc(circle_progress, -90, progress/totalProgress*360, false, paint_progress);
				}else if(style_type==1){
					canvas.drawArc(circle_progress, -90, progress/totalProgress*360, true, paint_progress);
				}
			}
			canvas.drawText((int)progress+"/"+(int)totalProgress, getLeft()+getWidth()/2, getTop()+getHeight()/2+textSize/4, paint_text);
		}
	}

}

2:attr属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
 	<!--declare-styleable:声明样式类型;attr name=""声明属性名;format="属性的类型"  -->
    <declare-styleable name="CustomEditText">
        <attr name="lineColor" format="color" />
        <attr name="lineHeight" format="dimension"/>
    </declare-styleable>
    <declare-styleable name="CustomView">
        <attr name="stroke_width" format="dimension"/>
        <attr name="circleColor" format="color"/>
        <attr name="secondCircleColor" format="color"/>
        <attr name="progress" format="float"/>
        <attr name="totalProgress" format="float"/>
        <attr name="textSize" format="dimension"/>
        <attr name="style_Type">
            <enum name="stroke" value="0"/>
            <enum name="stroke_and_fill" value="1"/>
        </attr>
    </declare-styleable>

</resources>

3:xml布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <com.anqiansong.views.CustomView
        xmlns:circle="http://schemas.android.com/apk/res/com.anqiansong.androidcustomview"
        android:id="@+id/customview"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerInParent="true"
        circle:circleColor="#000000"
        circle:secondCircleColor="#ff0000"
        circle:stroke_width="2dp"
        circle:totalProgress="100" 
        circle:progress="10"
        circle:style_Type="stroke"
        />

</RelativeLayout>

当xml文件中circle:style_Type="stroke"时



当xml文件中circle:style_Type="stroke_and_fill"时

4:activity中调用

public class MainActivity extends ActionBarActivity {

	CustomView customView;
	private float progress=0;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		customView=(CustomView) findViewById(R.id.customview);
		handler.sendEmptyMessageDelayed(0, 1000);
	}
	Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
			if(msg.what==0){
				if(progress>100){
					return;
				}else{
					customView.setProgress(progress);
					progress+=2;
					handler.sendEmptyMessageDelayed(0, 100);
				}
			}
		};
	};


}


当xml文件中circle:style_Type="stroke_and_fill"时

相关文章
|
3天前
|
API Android开发 开发者
Android经典实战之使用ViewCompat来处理View兼容性问题
本文介绍Android中的`ViewCompat`工具类,它是AndroidX库核心部分的重要兼容性组件,确保在不同Android版本间处理视图的一致性。文章列举了设置透明度、旋转、缩放、平移等功能,并提供了背景色、动画及用户交互等实用示例。通过`ViewCompat`,开发者可轻松实现跨版本视图操作,增强应用兼容性。
21 5
|
18天前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
View的绘制和事件处理是两个重要的主题,上一篇《图解 Android事件分发机制》已经把事件的分发机制讲得比较详细了,这一篇是针对View的绘制,View的绘制如果你有所了解,基本分为measure、layout、draw 过程,其中比较难理解就是measure过程,所以本篇文章大幅笔地分析measure过程,相对讲得比较详细,文章也比较长,如果你对View的绘制还不是很懂,对measure过程掌握得不是很深刻,那么耐心点,看完这篇文章,相信你会有所收获的。
39 2
|
11天前
|
XML 前端开发 Android开发
Android经典实战之Kotlin中实现圆角图片和圆形图片
本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。
13 0
|
1月前
|
Android开发
Android面试题之View的invalidate方法和postInvalidate方法有什么区别
本文探讨了Android自定义View中`invalidate()`和`postInvalidate()`的区别。`invalidate()`在UI线程中刷新View,而`postInvalidate()`用于非UI线程,通过消息机制切换到UI线程执行`invalidate()`。源码分析显示,`postInvalidate()`最终调用`ViewRootImpl`的`dispatchInvalidateDelayed`,通过Handler发送消息到UI线程执行刷新。
27 1
|
19天前
|
机器学习/深度学习 人工智能 算法
探索AI在医疗影像分析中的应用探索安卓开发中的自定义View组件
【7月更文挑战第31天】随着人工智能技术的飞速发展,其在医疗健康领域的应用日益广泛。本文将聚焦于AI技术在医疗影像分析中的运用,探讨其如何通过深度学习模型提高诊断的准确性和效率。我们将介绍一些关键的深度学习算法,并通过实际代码示例展示这些算法是如何应用于医学影像的处理和分析中。文章旨在为读者提供对AI在医疗领域应用的深刻理解和实用知识。
22 0
|
26天前
|
消息中间件 调度 Android开发
Android经典面试题之View的post方法和Handler的post方法有什么区别?
本文对比了Android开发中`View.post`与`Handler.post`的使用。`View.post`将任务加入视图关联的消息队列,在视图布局后执行,适合视图操作。`Handler.post`更通用,可调度至特定Handler的线程,不仅限于视图任务。选择方法取决于具体需求和上下文。
26 0
|
3月前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
79 1
|
3月前
|
XML API Android开发
Android 自定义View 之 圆环进度条
Android 自定义View 之 圆环进度条
|
3月前
|
XML API Android开发
Android 自定义View 之 饼状进度条
Android 自定义View 之 饼状进度条