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"时

相关文章
|
2月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
31 1
|
3月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
115 0
|
2月前
|
XML 前端开发 Android开发
Android:UI:Drawable:View/ImageView与Drawable
通过本文的介绍,我们详细探讨了Android中Drawable、View和ImageView的使用方法及其相互关系。Drawable作为图像和图形的抽象表示,提供了丰富的子类和自定义能力,使得开发者能够灵活地实现各种UI效果。View和ImageView则通过使用Drawable实现了各种图像和图形的显示需求。希望本文能为您在Android开发中使用Drawable提供有价值的参考和指导。
46 2
|
2月前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
2月前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
44 5
|
3月前
|
缓存 数据处理 Android开发
在 Android 中使用 RxJava 更新 View
【10月更文挑战第20天】使用 RxJava 来更新 View 可以提供更优雅、更高效的解决方案。通过合理地运用操作符和订阅机制,我们能够轻松地处理异步数据并在主线程中进行 View 的更新。在实际应用中,需要根据具体情况进行灵活运用,并注意相关的注意事项和性能优化,以确保应用的稳定性和流畅性。可以通过不断的实践和探索,进一步掌握在 Android 中使用 RxJava 更新 View 的技巧和方法,为开发高质量的 Android 应用提供有力支持。
|
3月前
|
缓存 调度 Android开发
Android 在子线程更新 View
【10月更文挑战第21天】在 Android 开发中,虽然不能直接在子线程更新 View,但通过使用 Handler、AsyncTask 或 RxJava 等方法,可以实现子线程操作并在主线程更新 View 的目的。在实际应用中,需要根据具体情况选择合适的方法,并注意相关的注意事项和性能优化,以确保应用的稳定性和流畅性。可以通过不断的实践和探索,进一步掌握在子线程更新 View 的技巧和方法,为开发高质量的 Android 应用提供支持。
46 2
|
3月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
|
3月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
Android面试高频知识点(3) 详解Android View的绘制流程
29 2
|
1月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
53 19