android打造酷炫自定义ProgressBar
来源:互联网 发布:php log打印到日志 编辑:程序博客网 时间:2024/05/25 21:33
自定义控件分三步:
1.自定义属性的声明与获取:
(1)找到value文件夹,新建一个名为attrs的xml文件:
由图可以看出:需要打造的水平进度条的progressbar需要有哪些自定义属性呢?基本需要七个属性:
a.左边已完成的进度reachbar需要高度reachbarheight
b.左边已完成的进度reachbar需要颜色reachbarcolor
c.中间的文字需要大小textsize
d.中间的文字需要颜色textcolor
e.中间的文字需要与Bar之间的间隔textoffset
f.右边未完成的进度unreachbar需要颜色unreachbarcolor
g.右边未完成的进度unreachbar需要高度unreachbarheight
所以我们需要对这七个属性进行声明
<attr name="progress_unreach_color" format="color"></attr><attr name="progress_unreach_height" format="dimension"></attr><attr name="progress_reach_color" format="color"></attr><attr name="progress_reach_height" format="dimension"></attr><attr name="progress_text_size" format="dimension"></attr><attr name="progress_text_color" format="color"></attr><attr name="progress_text_offset" format="dimension"></attr>
声明后,我们需要新建一个继承自ProgressBar 的view命名为HorizontalProgressbar,然后在attrs文件中的declare-styleable标签中进行使用:
<declare-styleable name="HorizontalProgressBar"> <attr name="progress_unreach_color" ></attr> <attr name="progress_unreach_height" ></attr> <attr name="progress_reach_color" ></attr> <attr name="progress_reach_height" ></attr> <attr name="progress_text_size" ></attr> <attr name="progress_text_color" ></attr> <attr name="progress_text_offset" ></attr></declare-styleable>(2)获取自定义属性:
private void obtainStyledattrs(AttributeSet attrs) { TypedArray ta=getContext().obtainStyledAttributes(attrs,R.styleable.HorizontalProgressBar); mTextSize=(int)ta.getDimension(R.styleable.HorizontalProgressBar_progress_text_size,mTextSize); mTextColor=ta.getColor(R.styleable.HorizontalProgressBar_progress_text_color,mTextColor); mTextOffset=(int)ta.getDimension(R.styleable.HorizontalProgressBar_progress_text_offset,mTextOffset); mReachColor=ta.getColor(R.styleable.HorizontalProgressBar_progress_reach_color,mReachColor); mReachHeight=(int)ta.getDimension(R.styleable.HorizontalProgressBar_progress_reach_height,mReachHeight); mUnReachColor=ta.getColor(R.styleable.HorizontalProgressBar_progress_unreach_color,mUnReachColor); mUnReachHeight=(int)ta.getDimension(R.styleable.HorizontalProgressBar_progress_unreach_height,mUnReachHeight); ta.recycle();}
2.控件的测量onMeasure()
onMeasure(widthMeasureSpec,heightMeasureSpec)方法中我们需要得到控件的宽高的模式,以及它的具体值,
int widthMode=MeasureSpec.getMode(widthMeasureSpec);int widthVal=MeasureSpec.getSize(widthMeasureSpec);得到测量模式之后,与三种模式相比较,如果模式是EXACTLY,也就是说用户给的是准确值的话,那么就直接将用户给定的结果作为测量值,如果是其他两种模式,那么就需要自己去测量控件的值,由图可知,整个控件的高度是由ReachBar和Text以及UnReachBar三者高度的最大值来决定,这就要求我们对Text的值进行测量,Text的值可以通过画笔的descent和ascent来测量。此处贴上代码:
private int measureHeight(int heightMeasureSpec) { int result=0; int heightMode=MeasureSpec.getMode(heightMeasureSpec); int heightSize=MeasureSpec.getSize(heightMeasureSpec); if (heightMode==MeasureSpec.EXACTLY){ //如果用户给定了精确值,那么就直接给将heightSize设置为测量值 result=heightSize; }else { //如果是其他两种模式, int textHeight=(int) (mPaint.descent()-mPaint.ascent()); result=getPaddingTop()+getPaddingBottom()+Math.max(Math.max(mReachHeight,mUnReachHeight),Math.abs(textHeight)); if (heightMode==MeasureSpec.AT_MOST){ result=Math.min(result,heightSize); } } return result;}最后就是要将测量后的宽高重新设置给控件:
@Overrideprotected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode=MeasureSpec.getMode(widthMeasureSpec); int widthVal=MeasureSpec.getSize(widthMeasureSpec); int height=measureHeight(heightMeasureSpec); setMeasuredDimension(widthVal,height); mRealWidth=getMeasuredWidth()-getPaddingLeft()-getPaddingRight();}3.绘制控件onDraw()方法
根据属性分别绘制控件中的三部分,reachBar,UnReachBar和text
@Overrideprotected synchronized void onDraw(Canvas canvas) { canvas.save(); canvas.translate(getPaddingLeft(),getHeight()/2); boolean noNeedUnReach=false; float radio=getProgress()*1.0f/getMax(); //得到文本的宽度 String text=getProgress()+"%"; int textWidth=(int)mPaint.measureText(text); float progressX=radio*mRealWidth; if (progressX+textWidth>mRealWidth){ progressX=mRealWidth-textWidth; noNeedUnReach=true; } float endX=radio*mRealWidth-mTextOffset/2;//reachBar的绘制结尾 if (endX>0){ mPaint.setColor(mReachColor); mPaint.setStrokeWidth(mReachHeight); canvas.drawLine(0,0,endX,0,mPaint); } //draw text mPaint.setColor(mTextColor); int y=(int)(-(mPaint.descent()+mPaint.ascent())/2); canvas.drawText(text,progressX,y,mPaint); //draw UnReachBar if (!noNeedUnReach){ float start=progressX+textWidth+mTextOffset/2; mPaint.setColor(mUnReachColor); mPaint.setStrokeWidth(mUnReachHeight); canvas.drawLine(start,0,mRealWidth,0,mPaint); } canvas.restore();}这就是自定义控件的三个流程,最后在测试一下就完美了;
其中的进度条的颜色和文本颜色高度都可以控制。
阅读全文
0 0
- android打造酷炫自定义ProgressBar
- 【ProgressBar】Android 自定义ProgressBar集锦
- 【Android自定义控件】打造炫酷进度条
- android自定义标题栏progressBar
- android 自定义ProgressBar
- Android 自定义ProgressBar (一)
- android自定义progressbar
- Android 自定义progressbar
- android 自定义progressbar
- Android自定义RatingBar && ProgressBar
- Android 自定义ProgressBar
- Android开发 自定义ProgressBar
- android自定义ProgressBar
- Android中自定义ProgressBar
- 【Android】自定义ProgressBar
- Android 自定义ProgressBar
- android 自定义ProgressBar
- Android progressBar 自定义
- objdump命令的使用[转载]
- 球面点三维坐标到纹理二维坐标的转换
- Linux查看物理CPU个数、核数、逻辑CPU个数
- sandbox
- Ubuntu下安装Opencv2.4.9 及实现python接口
- android打造酷炫自定义ProgressBar
- 【Java并发之】BlockingQueue
- json读取数据:ValueError: Extra data: line 77 column 2
- 网络编程中的常用函数整理
- 怎么搞积分
- Unsupported major.minor version 51.0 JDK版本错误
- JS按时间戳去分类
- XML文件报错dubbo:XX解决方法
- 关于香橙派H3的一些问题