android 自定义进度条

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);

    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值