android 自定义进度条

来源:互联网 发布:sublime text 3运行js 编辑:程序博客网 时间:2024/06/05 06:02

android 自定义进度条

  效果图,一个是逆时针,一个是个U型 ![效果一](http://img.blog.csdn.net/20160818214629661) ![效果二](http://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);    }}
0 0