您的位置:首页 > 移动开发 > Android开发

Android自定义答题进度条

2015-06-26 11:43 399 查看
看到公司项目原型图上有个答题进度条



刚好没什么事情就自定义一个View

首先是分析需要的属性

<attr name="maxprogrss" format="integer"></attr> <!-- 最大的进度 -->
<attr name="curprogrss" format="integer"></attr><!-- 当前的进度 -->
<attr name="linelength" format="dimension"></attr><!-- 线的长度 为防止圆和线连接处有缺口,线长度为圆心之间距离 -->
<attr name="circlediameter" format="dimension"></attr><!-- 圆的直径 -->
<attr name="lineheight" format="dimension"></attr><!-- 线的高度 -->
<attr name="selectedcolor" format="color"></attr><!-- 当前进度颜色 -->
<attr name="noselectedcolor" format="color"></attr><!-- 其他颜色 -->

<declare-styleable name="MyProgress">
<attr name="maxprogrss"></attr>
<attr name="curprogrss"></attr>
<attr name="linelength"></attr>
<attr name="circlediameter"></attr>
<attr name="lineheight"></attr>
<attr name="selectedcolor"></attr>
<attr name="noselectedcolor"></attr>
</declare-styleable>


自定义View的类
package com.sunrui.progressbar;

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.TypedValue;
import android.view.View;
import android.view.View.MeasureSpec;

public class MyProgress extends View {

private int maxProgress;
private int curProgress;
private int lineHeight;
private int lineLength;
private int circleDiameter;
private int selectedColor;
private int noSelectedColor;
private int width = 0;
private int height = 0;
private int w;
private int h;

public MyProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

public MyProgress(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.MyProgress, 0, 0);
int n = typedArray.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = typedArray.getIndex(i);
switch (attr) {
case R.styleable.MyProgress_maxprogrss:
maxProgress = typedArray.getInteger(i, 5);
break;
case R.styleable.MyProgress_curprogrss:
curProgress = typedArray.getInteger(i, 5);
curProgress = curProgress > maxProgress ? maxProgress
: curProgress;
break;
case R.styleable.MyProgress_lineheight:
lineHeight = typedArray.getDimensionPixelSize(attr,
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_PX, 6, getResources()
.getDisplayMetrics()));
break;
case R.styleable.MyProgress_linelength:
lineLength = typedArray.getDimensionPixelSize(attr,
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_PX, 32, getResources()
.getDisplayMetrics()));
;
break;
case R.styleable.MyProgress_circlediameter:
circleDiameter = typedArray.getDimensionPixelSize(attr,
(int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_PX, 32, getResources()
.getDisplayMetrics()));
;
break;
case R.styleable.MyProgress_selectedcolor:
selectedColor = typedArray.getColor(attr, Color.BLUE);
break;
case R.styleable.MyProgress_noselectedcolor:
noSelectedColor = typedArray.getColor(attr, Color.BLUE);
default:
break;
}
}
init();
}

public MyProgress(Context context) {
super(context);
init();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int w = circleDiameter + (maxProgress - 1) * lineLength;
int h = circleDiameter > lineHeight ? circleDiameter : lineHeight;

int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);

switch (specMode) {
case MeasureSpec.EXACTLY:
width = getPaddingLeft() + getPaddingRight() + specSize;
break;
case MeasureSpec.AT_MOST:
width = getPaddingLeft() + getPaddingRight() + w;
break;
}

specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);

switch (specMode) {
case MeasureSpec.EXACTLY:
height = getPaddingTop() + getPaddingBottom() + specSize;
break;
case MeasureSpec.AT_MOST:
height = getPaddingTop() + getPaddingBottom() + h;
break;
}
setMeasuredDimension(width, height);
}

@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < maxProgress; i++) {
RectF oval = new RectF(lineLength * i, height / 2 - circleDiameter
/ 2, lineLength * i + circleDiameter, height / 2
+ circleDiameter / 2);

if (curProgress - 1 > i) {
canvas.drawLine(circleDiameter / 2 + lineLength * i,
height / 2, circleDiameter / 2 + lineLength * (i + 1),
height / 2, linePaint);
}
if (curProgress <= i) {
canvas.drawArc(oval, 0, 360, false, nocirclePaint);
}else{
canvas.drawArc(oval, 0, 360, false, circlePaint);
}

}
}

public void setCurProgress(int curProgress) {
curProgress = curProgress > maxProgress ? maxProgress : curProgress;
curProgress = curProgress < 0 ? 0 : curProgress;
this.curProgress = curProgress;
postInvalidate();
}

private Paint linePaint, circlePaint, nocirclePaint;

private void init() {
linePaint = new Paint();
circlePaint = new Paint();
nocirclePaint = new Paint();
nocirclePaint.setColor(noSelectedColor);
circlePaint.setColor(selectedColor);
linePaint.setColor(selectedColor);
linePaint.setStrokeWidth(lineHeight);
}

}


layout文件

<com.sunrui.progressbar.MyProgress
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:maxprogrss="5"
custom:curprogrss="3"
custom:linelength="130px"
custom:lineheight="12px"
custom:circlediameter="52px"
custom:selectedcolor="#0000ff"
android:layout_centerInParent="true"
custom:noselectedcolor="#d3d3d3"/>


使用

myProgress = (MyProgress) findViewById(R.id.progress);
myProgress.setCurProgress(4);


效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: