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

android 自定义进度条

2016-08-18 21:32 337 查看

android 自定义进度条

效果图,一个是逆时针,一个是个U型
![效果一](https://img-blog.csdn.net/20160818214629661)
![效果二](https://img-blog.csdn.net/20160818214704974)

步骤一:自定义进度条属性


在values中新建一个资源文件 my_round_progress_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

<declare-styleable name="MyRoundProgressBar">
<attr name="unreachHeight" format="dimension"></attr>
<attr name="unreachColor" format="color"></attr>
<attr name="reachHeight" format="dimension"></attr>
<attr name="reachColor" format="color" ></attr>
<attr name="progressRadius" format="dimension"></attr>
<attr name="progressTextSize" format="dimension"></attr>
<attr name="upLikeU" format="boolean"></attr>
</declare-styleable>
</resources>


步骤二:新建组件MyRoundProgressBar extends ProgressBar;主要是重写onMeasure和onDraw方法

public class MyRoundProgressBar extends ProgressBar{
//一些自定义的属性,并赋予一些默认值
private int mradius=dp2px(50);    //圆的半径,默认50dp
private int unreachHeight=2;    //该进度条未完成部分的宽度
private int unreachColor=0Xa0ff0000;//未完成的颜色
private int reachHeight=10;   //已完成部分的宽度
private int reachColor=0XFF0099ff;//已完成部分的颜色
private int textSize=sp2px(20);  //字体颜色
private boolean upLikeU=false;   //是否U型显示

private int maxPaintWidth=3;  //reachHeight与unreachHeight两者的最大值

private Paint paint=new Paint();

public MyRoundProgressBar(Context context) {
//注意---这里不要用super.(context)
this(context,null);
}

public MyRoundProgressBar(Context context, AttributeSet attrs) {
//注意---这里不能要super.(context,attrs)
this(context, attrs,0);
}

public MyRoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取布局文件中进度条的自定义属性值
TypedArray ta=getContext().obtainStyledAttributes(attrs,R.styleable.MyRoundProgressBar);
//圆的半径、文本大小、是否u型显示
//MyRoundProgressBar_progressRadius表明为MyRoundProgressBar的progressRadius属性,第二个参数为默认值
mradius= (int) ta.getDimension(R.styleable.MyRoundProgressBar_progressRadius,mradius);
textSize= (int) ta.getDimension(R.styleable.MyRoundProgressBar_progressTextSize,textSize);
upLikeU=ta.getBoolean(R.styleable.MyRoundProgressBar_upLikeU, false);

//获取未完成部分的宽度,颜色
unreachHeight= (int) ta.getDimension(R.styleable.MyRoundProgressBar_unreachHeight,unreachHeight);
unreachColor=ta.getColor(R.styleable.MyRoundProgressBar_unreachColor,unreachColor);

//获取完成部分的宽度、颜色
reachHeight= (int) ta.getDimension(R.styleable.MyRoundProgressBar_reachHeight,reachHeight);
reachColor=ta.getColor(R.styleable.MyRoundProgressBar_reachColor,reachColor);

ta.recycle();//记得recycle
}

@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
maxPaintWidth=Math.max(unreachHeight,reachHeight);

//desire为组件想要的宽度=直径+左右 padding+圆圈的最大宽度
int desire=mradius*2+getPaddingLeft()+getPaddingRight()+maxPaintWidth;
//获取组件能够得到的宽度和高度
int width=resolveSize(desire,widthMeasureSpec);
int height=resolveSize(desire,heightMeasureSpec);

//因为是个圆,所以我们取得到的宽度和高度的最小值(最大也可),作为组件的宽高
int realWidth=Math.min(width,height);
setMeasuredDimension(realWidth,realWidth);
//近算出进度条真正的半径
mradius=(realWidth-getPaddingLeft()-getPaddingRight()-maxPaintWidth)/2;
Log.i("my bar",mradius+" ");

}

@Override
protected synchronized void onDraw(Canvas canvas) {
//注意要save和restore
canvas.save();
//平移画布坐标,以便画图和写文字
canvas.translate(getPaddingLeft()+maxPaintWidth/2,getPaddingTop()+maxPaintWidth/2);

//写文字:读者可以自己尝试添加文字颜色的属性到属性集中
//设置画笔
paint.setColor(Color.GREEN);//
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(textSize);
String text=getProgress()+"%";
//获取该字符串画出来的宽高
int textWidth= (int) paint.measureText(text);
int textHeight=(int)(paint.descent()+paint.ascent());
//第二三个参数为文字左上角的坐标
canvas.drawText(text,mradius-textWidth/2,mradius-textHeight/2,paint);

//画为未完成部分,一个圆
paint.setStrokeWidth(unreachHeight);//设置未完成的宽度
paint.setColor(unreachColor);
//设置锯齿和抖动
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
//参数一二为圆心,三位半径
canvas.drawCircle(mradius,mradius,mradius,paint);

//画完成部分,一个圆弧
paint.setColor(reachColor);
paint.setStrokeWidth(reachHeight);
//计算圆弧角度
int angle= (int) (getProgress()*1.0/getMax()*360);
//根据是否为u型来画圆弧,第一个参数为该圆弧对应的圆的外切正方形
//二为起始角度,三为圆弧角度大小
if(upLikeU)
canvas.drawArc(new RectF(0,0,2*mradius,2*mradius),90-angle/2,angle,false,paint);
else
canvas.drawArc(new RectF(0,0,2*mradius,2*mradius),0,angle,false,paint);

canvas.restore();
}

//坐标的转换函数
private int dp2px(int dpVal)
{
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dpVal,getResources().getDisplayMetrics());
}
private int sp2px(int spVal)
{
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,spVal,getResources().getDisplayMetrics());
}
public void showProgressBarMessage()
{
Log.i("my bar"," " +mradius+" "+textSize+" "+unreachHeight+" "+unreachColor+" "+reachHeight+" "+reachColor);
System.out.print("my bar "+" bar arguments " +mradius+" "+textSize+" "+unreachHeight+" "+unreachColor+" "+reachHeight+" "+reachColor);
}
}


步骤三:调用–在布局文件中使用,在java代码中更改进度值

<com.example.myview.MyRoundProgressBar
android:id="@+id/myProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:progress="30"
myprogress:progressRadius="50dp"
myprogress:progressTextSize="30sp"
myprogress:unreachColor="#09f"
myprogress:unreachHeight="3dp"
myprogress:reachHeight="10dp"
myprogress:reachColor="#FF0099ff"
myprogress:upLikeU="true"
></com.example.myview.MyRoundProgressBar>


public class MainActivity extends Activity {
private MyRoundProgressBar progress;
private int tag=0x45623;

//定义一个handler,每隔0.1s增加进度
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what==tag)
{
int val=progress.getProgress();
val++;
//如果进度尚未达到最大值
if(val<=progress.getMax())
{
progress.setProgress(val);
handler.sendEmptyMessageDelayed(tag, 100);
progress.showProgressBarMessage();
}
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress=(MyRoundProgressBar) findViewById(R.id.myProgress);
//开始更改进度
handler.sendEmptyMessage(tag);

}

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