Android自定义View之圆形进度条
2016-04-08 23:05
411 查看
Android自定义View之圆形进度条
尽管github上的开源圆形进度条已经很多了,但是我仍然希望能通过自己完成一个,接下来我就一步一步实现圆形进度条,今天我们要实现的效果图如下:观察上面两幅图我们可以看到,这个图形是由两部分组成的中间的圆形+外围的弧形,我们自然而然的想到了用canvas画。想好就开始实践,
新建PercentDigitalView项目,新建view包,新建PercentDigitalView继承自View,项目结构如下:
接下来我们在为PercentDigitalView添加构造函数,并重写onDraw方法,修改后完整代码如下:
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import android.view.ViewTreeObserver; import com.tt.percentdigitalview.R; /** * Created by TuoZhaoBing on 2016/4/8 0007. */ public class PercentDigitalView extends View { public static final String TAG = "PercentDigitalView"; public PercentDigitalView(Context context) { super(context); } public PercentDigitalView(Context context, AttributeSet attrs) { super(context, attrs); } public PercentDigitalView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } }
接着来的工作就是画圆和画弧了,添加画笔并进行画笔的初始化,如下两段代码:
private Paint mCirclePaint,mArcPaint,mTextPaint;
public void init(Context context,AttributeSet attrs){ mContext = context; mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mCirclePaint.setStyle(Paint.Style.FILL); mTextPaint.setStyle(Paint.Style.FILL); mArcPaint.setStyle(Paint.Style.STROKE); mTextPaint.setColor(Color.BLACK); mCirclePaint.setColor(Color.GREEN); mArcPaint.setColor(Color.GREEN); }
另外我们要画圆,画弧肯定有圆心,圆的半径和弧的宽度,还有弧度的百分比,将这些定义好,并初始化,如下面两段代码:
private int mCircleX; private float mRadius; private int mTmpSweepValue =0,mSweepValue; private RectF mInnerArcRectF; public String mShowText = "%"; private int mWidth,mHeight; private int mInnerArcWidth;
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PercentDigitalView); mRadius = ta.getInteger(R.styleable.PercentDigitalView_innerCircleRadius,100); mInnerArcWidth = ta.getInteger(R.styleable.PercentDigitalView_ringWidth,50); mSweepValue = ta.getInteger(R.styleable.PercentDigitalView_ringPercent,350); ta.recycle();
这里我默认绘制圆心在该View的水平中心,所以我实现了
ViewTreeObserver.OnGlobalLayoutListener具体的实现函数的代码如下:
@Override public void onGlobalLayout() { mWidth = getWidth(); mHeight = getHeight(); }
做好了准备工作,重点戏就来了,接下来我们在onDraw中进行圆,圆弧和字符的绘制,代码如下:
mCircleX = mWidth/2; mInnerArcRectF = new RectF((float) (mWidth*0.1), (float) (mWidth*0.1), (float) (mWidth*0.9), (float) (mWidth*0.9)); canvas.drawCircle(mCircleX,mCircleX,mRadius,mCirclePaint); canvas.drawArc(mInnerArcRectF,270,mTmpSweepValue,false,mArcPaint); java.text.DecimalFormat df=new java.text.DecimalFormat("#.##"); canvas.drawText(mShowText+(df.format(mTmpSweepValue*100/360d)),0,mShowText.length()+(df.format(mTmpSweepValue*100/360d)+"").length(),mCircleX,mCircleX+(mShowText.length()/4),mTextPaint); if (mTmpSweepValue < mSweepValue){ mTmpSweepValue += 1; postInvalidate(); } super.onDraw(canvas);
至此,我们就完成了PercentDigitalView的全部编码,该类的完整代码如下:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import com.tt.percentdigitalview.R;
/**
* Created by TuoZhaoBing on 2016/4/7 0007.
*/
public class PercentDigitalView extends View implements ViewTreeObserver.OnGlobalLayoutListener{
public static final String TAG = "PercentDigitalView";
private Context mContext;
private int mCircleX;
private float mRadius;
private int mTmpSweepValue =0,mSweepValue;
private RectF mInnerArcRectF;
private Paint mCirclePaint,mArcPaint,mTextPaint;
public String mShowText = "%";
private int mWidth,mHeight;
private int mInnerArcWidth;
public PercentDigitalView(Context context) {
super(context);
init(context,null);
}
public PercentDigitalView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
public PercentDigitalView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}
public void init(Context context,AttributeSet attrs){
mContext = context;
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PercentDigitalView); mRadius = ta.getInteger(R.styleable.PercentDigitalView_innerCircleRadius,100); mInnerArcWidth = ta.getInteger(R.styleable.PercentDigitalView_ringWidth,50); mSweepValue = ta.getInteger(R.styleable.PercentDigitalView_ringPercent,350); ta.recycle();
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaint.setStyle(Paint.Style.FILL);
mTextPaint.setStyle(Paint.Style.FILL);
mArcPaint.setStyle(Paint.Style.STROKE);
mTextPaint.setColor(Color.BLACK);
mCirclePaint.setColor(Color.GREEN);
mArcPaint.setColor(Color.GREEN);
mArcPaint.setStrokeWidth((float)(mInnerArcWidth));
getViewTreeObserver().addOnGlobalLayoutListener(this);
}
@Override
protected void onDraw(Canvas canvas) {
mCircleX = mWidth/2; mInnerArcRectF = new RectF((float) (mWidth*0.1), (float) (mWidth*0.1), (float) (mWidth*0.9), (float) (mWidth*0.9)); canvas.drawCircle(mCircleX,mCircleX,mRadius,mCirclePaint); canvas.drawArc(mInnerArcRectF,270,mTmpSweepValue,false,mArcPaint); java.text.DecimalFormat df=new java.text.DecimalFormat("#.##"); canvas.drawText(mShowText+(df.format(mTmpSweepValue*100/360d)),0,mShowText.length()+(df.format(mTmpSweepValue*100/360d)+"").length(),mCircleX,mCircleX+(mShowText.length()/4),mTextPaint); if (mTmpSweepValue < mSweepValue){ mTmpSweepValue += 1; postInvalidate(); } super.onDraw(canvas);
}
@Override
public void onGlobalLayout() {
mWidth = getWidth();
mHeight = getHeight();
}
}
完整项目源码下载地址:github
相关文章推荐
- Android学习(8) -- 短信发送器
- Android Context简介
- Android设备标识符的使用
- 使用Android studio 出现的问题解决
- Android Studio 2.0 新版模拟器
- Android Studio如何发布APK
- Android API讲解之:BitmapFactory
- 使用 Intel HAXM 为 Android 模拟器加速
- android studio运行时报错the selected device is incompatible
- vlc for android中的数据绑定(Data Binding)
- Android矩形Bitmap转为圆形
- android RelativeLayout属性和使用, 实现上面view叠加在下面view之上的效果
- 关于Android的ActionBar不能显示左上角的图标解决方案
- Android中深入理解 LayoutInflater.inflate()
- Android-使用ViewFlipper制作图片轮播器
- Android文件下载之进度检测
- Android EditText 编辑框的使用
- Android 关于 OnScrollListener 事件顺序次数的简要分析
- Android 6.0 运行时权限处理完全解析
- Android编程之LocalBroadcastManager源码详解