Android自定义控件(二)——圆形进度条以及回调方法
来源:互联网 发布:龙华数据恢复 编辑:程序博客网 时间:2024/06/15 21:06
(一)引言
上一篇博客介绍了Android自定义控件中音量控制器的实现方法,没有看过的盆友可以传送到http://blog.csdn.net/a253664942/article/details/45017283看看。今天准备给大家介绍一下圆形进度条的实现方式。
首先看一下最终的实现效果,来上图:
进度条的背景进度的颜色、进度的颜色以及字体的颜色、圆环的半径和宽度都可以使用自定义属性来改变,另外,还添加了一个onProgressListener监听器,其中有一个onEnd回调方法,用来处理当进度条到达最大值时的事件。各位看官如果喜欢,也可以自己加一些回调方法,比如onStart方法用来监听到进度开始执行的回调方法。
(二)代码实现
1.自定义类
首先自定义一个CircleProgressView类继承View,然后声明各种属性:进度条的半径,宽度,颜色等以及回调函数。源码中有很详细的注释,一看就明白,这里就不再赘述了。
public class CircleProgressView extends View {private Paint mPaintBackground; // 绘制背景圆环的画笔private Paint mPaintProgress; // 绘制背景进度的画笔private Paint mPaintText; // 绘制背景字体的画笔private int bgColor = Color.WHITE; // 背景圆环的颜色private int textColor = Color.CYAN; // 字体的颜色private int progressColor = Color.CYAN; // 进度条的颜色private float mStrokeWidth = 10;// 背景圆环的宽度private float mRadius = 60; // 背景圆环的半径private RectF rectPro;// 进度条的绘制外接矩形private int mProgress = 0; // 当前进度private int mMaxProgress = 100; // 最大进度private int mWidth, mHeight;private onProgressListener mOnProgressListener;public void setOnProgressListener(onProgressListener mOnProgressListener) {this.mOnProgressListener = mOnProgressListener;}/** * 回调接口 * */public interface onProgressListener{/** * 回调函数 当进度条满时调用此方法 */public void onEnd(); }
2.获得自定义属性
在构造方法中 获得xml文件中指定的自定义属性的值,以及初始化画笔。
public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub if(attrs!=null){ TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgress); int count = ta.getIndexCount(); for (int i = 0; i < count; i++) { int attr = ta.getIndex(i); switch (attr) { case R.styleable.CircleProgress_radius: mRadius = ta.getDimension(R.styleable.CircleProgress_radius, mRadius); break; case R.styleable.CircleProgress_strokeWidth: mStrokeWidth = ta.getDimension(R.styleable.CircleProgress_strokeWidth, mStrokeWidth); break; case R.styleable.CircleProgress_bgColor: bgColor = ta.getColor(R.styleable.CircleProgress_bgColor, bgColor); break; case R.styleable.CircleProgress_progressColor: progressColor = ta.getColor(R.styleable.CircleProgress_progressColor, progressColor); break; case R.styleable.CircleProgress_android_textColor: textColor = ta.getColor(R.styleable.CircleProgress_android_textColor, textColor); break; } } ta.recycle(); } initPaint(); }
initPaint方法是初始化画笔的函数。
private void initPaint() { mPaintBackground = new Paint(); mPaintBackground.setColor(bgColor); // 设置抗锯齿 mPaintBackground.setAntiAlias(true); // 设置防抖动 mPaintBackground.setDither(true); // 设置样式为环形 mPaintBackground.setStyle(Style.STROKE); // 设置环形的宽度 mPaintBackground.setStrokeWidth(mStrokeWidth); mPaintProgress = new Paint(); mPaintProgress.setColor(progressColor); // 设置抗锯齿 mPaintProgress.setAntiAlias(true); // 设置防抖动 mPaintProgress.setDither(true); // 设置样式为环形 mPaintProgress.setStyle(Style.STROKE); // 设置环形的宽度 mPaintProgress.setStrokeWidth(mStrokeWidth); mPaintText = new Paint(); mPaintText.setColor(textColor); // 设置抗锯齿 mPaintText.setAntiAlias(true); mPaintText.setTextAlign(Align.CENTER); mPaintText.setTextSize(40); }
progressColor、bgColor等都是自定义的属性,在attrs.xml文件中声明。见名知意,这些属性值的意思应该不难理解。
attrs.xml
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <attr name="bgColor" format="color|reference" /> <attr name="progressColor" format="color|reference" /> <attr name="radius" format="dimension" /> <attr name="strokeWidth" format="dimension" /> <declare-styleable name="CircleProgress"> <attr name="android:textColor" /> <attr name="bgColor" /> <attr name="progressColor" /> <attr name="radius" /> <attr name="strokeWidth" /> </declare-styleable></resources>
3.测量控件宽高
在onMeasure方法中测量控件的宽高,RectPro是进度条圆环外接矩形的范围。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub mWidth = getRealSize(widthMeasureSpec); mHeight = getRealSize(heightMeasureSpec); setMeasuredDimension(mWidth, mHeight); }private int getRealSize(int measureSpec) { int result = -1; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.UNSPECIFIED) { // 这两种模式需要自己计算 result = (int) (mRadius * 2 + mStrokeWidth*2); } else { result = size; } return result; } private void initRect() { if (rectPro == null) { rectPro = new RectF(); int viewSize = (int) (mRadius * 2); int left = (mWidth - viewSize) / 2; int top = (mHeight - viewSize) / 2; int right = left + viewSize; int bottom = top + viewSize; rectPro.set(left, top, right, bottom); }
这里可以画个图来便于大家理解。
在上图中,黑色边框内的范围代表父容器。而我们的控件的宽度等于直径的长度+加上边框的宽度*2。即 width =radius *2 + strokeWidth*2;
高度同理。
绿色的边框表示RectPro即进度条圆环外接矩形的范围。RectPro的left和top的坐标等于控件的宽度减去圆环直径然后除以2;right和bottom的坐标等于left的坐标加上直径。
4.绘制进度条
测量完控件的宽高之后,来到最重要的一步:onDraw方法中绘制进度条。
protected void onDraw(Canvas canvas) { float angle = mProgress / (mMaxProgress * 1.0f) * 360; // 圆弧角度 initRect(); //绘制背景圆环 canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mPaintBackground); //绘制进度条 canvas.drawArc(rectPro, -90, angle, false, mPaintProgress); //绘制字体 canvas.drawText(mProgress + "%", mWidth / 2, mHeight / 2, mPaintText); if (mProgress < mMaxProgress) { mProgress += 2; invalidate(); } //当进度到达最大值时 调用此函数 if(mOnProgressListener != null){ if(mProgress == mMaxProgress){ mOnProgressListener.onEnd(); } } }
我们控制进度条每次迭代2进度,只要进度条当前值小于最大值,则刷新视图重新绘制。最后,当进度条到达最大值时,我们调用回调方法。
5.使用自定义控件
在activity_main.xml中引用我们的自定义控件并设置属性。并在activity中使用我们的回调方法:当进度条到达最大值时,设置其进度为0,最终的效果时:进度条无限循环从0到100;
activity_main.xml
<com.custom.circleprogressview.CircleProgressView android:id="@+id/pro" android:layout_width="wrap_content" android:layout_height="wrap_content" app:bgColor="#FFFF00" app:progressColor="#FF0F00" app:radius = "100dip" app:strokeWidth = "10dip" />
activity中调用
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final CircleProgressView progressView = (CircleProgressView) findViewById(R.id.pro); progressView.setOnProgressListener(new onProgressListener() { public void onEnd() { // TODO Auto-generated method stub progressView.setProgress(0); } }); }
(三)总结
好了,收工!这次的自定义控件的实现中涉及到了很多的知识点:自定义属性的使用,自定义视图的绘制以及自己定义的回调接口。
其实大家可以发现,将这个案例改一改,我们就可以实现另外一种效果:小米音量控制器。很简单,只要将中间的字换成图片就可以了,然后改一下进度条的颜色~~
各位如果喜欢的话,可以留个言 点个赞~!
**
附上源码
**
- Android自定义控件(二)——圆形进度条以及回调方法
- Android自定义控件:圆形进度条
- 自定义控件—入门圆形进度条
- Android自定义控件之自定义圆形进度条
- 自定义圆形进度条(二)
- 圆形进度条+二维码扫描+自定义组合控件标题栏+自定义矩形view+接口回调方法
- Android自定义控件--圆形进度条(中间有图diao)
- android自定义控件之圆形进度条(带动画)
- Android自定义控件之圆形进度条ImageView
- Android自定义控件之圆形进度条
- Android 自定义控件实现圆形进度条
- Android自定义控件实现圆形进度条
- 自定义控件 圆形进度条
- 自定义控件-圆形进度条
- Android自定义控件系列之应用篇——圆形进度条
- Android自定义控件系列之应用篇——圆形进度条
- Android自定义控件系列之应用篇——圆形进度条
- 1.自定义控件简单开启——圆形进度条
- 关于单例设计模式的总结
- 去掉std::string或std::wstring的最后一个字符的简单方法
- Android 在TextView中使用AutoLink,并自定义点击链接后的行为
- ResultSet用法集锦
- java shiro、maven、Bootstrap、HTML5、SpringMVC、Mybatis、Hibernate、安全权限、高性能、高并发
- Android自定义控件(二)——圆形进度条以及回调方法
- The content of the adapter has changed but ListView did not receive a notification
- php上传文件大小限制解决方法
- JAVA连接MYSQL配置
- CSS实现自适应圆角矩阵——滑动门
- wstring,WCHAR,TCHAR,CHAR
- The superiority of the Chinese film faced plywood
- 用Eclipse 开发Dynamic Web Project应用程序
- DirectX9 初始化Direct3D通用框架