进度条是Android项目中常用的组件之一。本文将详细介绍自定义进度条的实现过程。有兴趣的朋友可以跟边肖学习一下。
目录
前言效果图实施步骤1。绘制背景圆形矩形2。画进度3。绘制文本4。添加动画完整代码。
前言
进度条是Android项目中常用的组件之一。想要了解它是如何实现的,首先需要了解自定义视图和Android坐标系的相关知识。我来详细介绍一下自定义进度条的实现过程。
这个项目的源代码:https://gitee.com/tu_erhongjiang/android-progress-bar
效果图
实现步骤
1.绘制背景圆形矩形
首先,画一个圆形矩形。矩形左上角和右下角的xy坐标传入RectF,用来确定矩形的位置和大小,然后在矩形内部画一个圆形矩形。
核心代码:canvas.drawRoundRect()
私有void drawBackground(画布canvas){
//圆角矩形
RectF rectF=new RectF(padding,padding,mWidth - padding,m height-padding);
canvas.drawRoundRect(rectF,round,round,mPaintRoundRect);
}
2.绘制进度
其实里面的进度条也是圆形长方形,只是进度条的笔刷是实心的。内部进度条矩形的大小需要比外部矩形略小,才能达到上述效果。如果进度条的矩形大于或等于背景矩形的大小,背景中的边框会被完全压下,只显示一个没有边框的进度条,所以这里需要减去strokeWidth。
私有void drawProgress(画布canvas){
如果(过程!=0){
RectF rect progress=new RectF(padding strokeWidth,padding stroke width,process,m height-padding-stroke width);//内部进度条
canvas . drawroundrect(rect progress,round,round,MP aint);
}
}
3.绘制文字
以下是如何使文本居中:
getWidth()/2得到的结果是中间位置的x坐标,但是如果从这里画出文字就无法达到居中的效果。因此,需要计算文本的长度,然后将整个文本向左移动。MTxtWidth/2是文本的中心,也就是说文本的中心可以通过移动到矩形的中心来居中。
私有void updateText(画布canvas) {
string finished text=get resources()。getString(r . string . finished);
String defaultText=getResources()。getString(r . string . default text);
int percent=(int)(process/(m width-padding-stroke width)* 100);
画画。font metrics FM=mpainttext . getfont metrics();
int mTxtWidth=(int)mpaintext . measure text(finished text,0,default text . length());
int mTxtHeight=(int)math . ceil(FM . descent-FM . ascent);
int x=getWidth()/2-mTxtWidth/2;//画布中文本的x坐标
int y=getHeight()/2 MTX height/4;//画布中文本的Y坐标
如果(百分比100) {
canvas.drawText(percent '% ',x,y,mPaintText);
}否则{
canvas.drawText(finishedText,x,y,mPaintText);
}
}
4.加入动画
最后,添加动画效果,使进度条移动。我在属性动画中使用了valueAnimator。这个动画不能直接修改view,类似于timer,需要我们传递一个数值范围和执行时间。比如3秒内从1到100。然后在接口回调时获取当前进度,执行invalid()方法查看,刷新UI。
//属性动画
public void start() {
value animator value animator=value animator . off float(0,m width-padding-stroke width);
valueAnimator.setDuration(持续时间);
value animator . set interpolator(new decelerate interpolator());
value animator . addupdatelistener(动画- {
process=(float)animation . getanimatedvalue();
invalidate();
});
value animator . start();
}
完整代码
包com . example . floating window . widget;
导入安卓。动画。价值动画师;
导入安卓。内容。语境;
导入安卓。图形。画布;
导入安卓。图形。油漆;
导入安卓。图形。rectf
导入安卓。util。attributeset
导入安卓。util。键入的值;
导入安卓。查看。查看;
导入安卓。查看。动画。减速插值器;
导入安卓克斯。注释。可空;
导入com。举例。浮动窗口。r;
公共类HorizontalProgressView扩展视图{
私漆mPaint
私漆mPaintRoundRect
私漆mPaintText
私有int mWidth
私有int mHeight
private int padding=5;
private int笔画宽度=8;
private int textSize=15
私长时长=3500;
私有整数回合
私有浮动过程;
公共HorizontalProgressView(上下文上下文){
超级(上下文);
init();
}
公共HorizontalProgressView(上下文上下文,@ Nullable attributes set attrs){
超级(上下文,attrs);
init();
}
公共HorizontalProgressView(上下文上下文,@ Nullable AttributeSet attrs,int defStyleAttr) {
super(context,attrs,defStyleAttr);
init();
}
//初始化画笔
私有void init(){
mpaitroundrect=new Paint();//圆角矩形
mpaintroundrect。设置颜色(获取资源().getColor(r . color。背));//圆角矩形颜色
mpaitroundrect。setantialias(真);//抗锯齿效果
mPaintRoundRect.setStyle(Paint .风格。笔画);//设置画笔样式
mpaitroundrect。setstrokewidth(strokeWidth);//设置画笔宽度
MP aint=new Paint();
MP int。设置颜色(获取资源().getColor(r . color。内心));
MP int。设置样式(绘画.风格。填充_和_笔画);
MP不是。setantialias(真);
MP不是。setstrokewidth(strokeWidth);
mPaintText=new Paint();
mpainttext。setantialias(真);
mPaintText.setStyle(Paint .风格。填充);
mpainttext。设置颜色(获取资源().getColor(r . color。背));
mpainttext。settextsize(sp2px(textSize));
}
public void set padding(int padding){
this.padding=填充;
}
public void setStrokeWidth(int strokeWidth){
这个。笔画宽度=笔画宽度;
}
public void setTextSize(int textSize){
这个。文本大小=文本大小;
}
公共void setDuration(长持续时间){
this.duration=持续时间;
}
@覆盖
受保护的测量时无效(int width measurespec,int heightMeasureSpec) {
超级棒。on measure(widthMeasureSpec,heightsmeasurespec);
int widthSpecMode=测量规格。获取模式(widthMeasureSpec);
int heightSpecMode=测量规格。获取模式(heightsmeasurespec);
int widthSpecSize=测量规格。getsize(widthMeasureSpec);
int heightSpecSize=测量规格。getsize(heightsmeasurespec);
//MeasureSpec .没错,精确尺寸
if (widthSpecMode==MeasureSpec .恰好|| widthSpecMode==MeasureSpec .最多){
mWidth=widthSpecSize
}否则{
m宽度=0;
}
//MeasureSpec .至多,最大尺寸,只要不超过父控件允许的最大尺寸即可,测量规格.未指明的未指定尺寸
if (heightSpecMode==MeasureSpec .至多|| heightSpecMode==MeasureSpec .未指定){
mHeight=默认高度();
}否则{
mHeight=heightSpecSize
}
//设置控件实际大小
圆=m高/2;//圆角半径
setMeasuredDimension(mWidth,m height);
}
@覆盖
受保护的void onDraw(画布画布){
super.onDraw(画布);
绘图背景(画布);//绘制背景矩形
绘图进度(画布);//绘制进度
更新文本(画布);//处理文字
}
私有空白绘图背景(画布画布){
RectF rectF=new RectF(padding,padding,mWidth - padding,m height-padding);//圆角矩形
canvas.drawRoundRect(rectF,round,round,mPaintRoundRect);
}
私有void drawProgress(画布画布){
如果(过程!=0){
RectF rect progress=new RectF(padding strokeWidth,padding stroke width,process,m height-padding-stroke width);//内部进度条
画布。drawroundrect(rect progress,round,round,MP aint);
}
}
私有void updateText(画布画布){
string完成text=get resources().getString(r . string。完了);
String defaultText=getResources().getString(r . string。默认文本);
int percent=(int)(进程/(m宽度-填充-笔画宽度)* 100);
画画字体度量FM=mpainttext。get font metrics();
int mTxtWidth=(int)mpaintext。测量文本(完成文本,0,默认文本。length());
int MTX height=(int)math。细胞(调频。下降调频。ascent);
int x=getWidth()/2-mTxtWidth/2;//文字在画布中的x坐标
int y=getHeight()/2 MTX高度/4;//文字在画布中的y坐标
如果(百分比100) {
canvas.drawText(percent '% ',x,y,mPaintText);
}否则{
canvas.drawText(finishedText,x,y,mPaintText);
}
}
//属性动画
public void start() {
价值动画师价值动画师=价值动画师。off float(0,m宽度-填充-笔画宽度);
valueAnimator.setDuration(持续时间);
价值动画师。设置插值器(新减速插值器());
价值动画师。addupdatelistener(动画- {
流程=(浮动)动画。getanimatedvalue();
invalidate();
});
价值动画师。start();
}
private int sp2px(int sp) {
返回(int)类型值。应用维度(键入得值.复杂单元sp,SP,
getResources().getDisplayMetrics());
}
//进度条默认高度,未设置高度时使用
private int defaultHeight() {
float scale=getContext().getResources().getDisplayMetrics().密度;
return (int) (20 * scale 0.5f * (20=0?1 : -1));
}
}
以上就是横向进度条的实现步骤,整体来说还是比较简单的,如果你对机器人坐标系和帆布比较熟悉的话自定义视角实现起来还是很容易的。
到此这篇关于机器人实现绚丽的自定义进度条的文章就介绍到这了,更多相关机器人自定义进度条内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。