android自定义一个带进度条的button

android自定义一个带进度条的button

android自带的progressbar有时候显得不够灵活,不能满足项目的需求,所以研究了下带进度条的button如何来实现。
其实实现这个功能可以有两个方法,一个是通过布局,一个是通过写一个类来继承view自己通过画布来绘制。这是效果图
第一个和第二个是通过画布来实现的,第三个是通过布局实现的。
先来说说第一种
其实就是两个矩形,一个是背景的矩形,一个是前面的进度条,也是一个矩形,再就是中间的文字。
核心代码:

   @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //开始画背景图片
        RectF oval = new RectF(0, 0, getWidth(), getHeight());
        mPaint.setColor(mBackgroundColor);
        canvas.drawRoundRect(oval, mCorner, mCorner, mPaint);


        //开始画里面的进度条   坐标是  左上角  右下角
        mPaint.setColor(mForcegroundColor);
        if (mProgress < mCorner) {
            oval = new RectF(0, mCorner - mProgress, (getWidth() * mProgress) / mMax, getHeight());
            canvas.drawRoundRect(oval, mProgress, mProgress, mPaint);
        } else {
            oval = new RectF(0, 0, (getWidth() * mProgress) / mMax, getHeight());
            canvas.drawRoundRect(oval, mCorner, mCorner, mPaint);
        }

        //开始画图片中间的文字
        if (mText == null) {
            return;
        }
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mTextSize);
        if (mProgress == 100) {
            mText = "完成";
        }

        float[] widths = new float[mText.length() - 1];
        mPaint.getTextWidths(mText, 0, mText.length() - 1, widths);

        float textWidth = 0;
        for (int i=0;i<widths.length;i++){
            textWidth+=widths[i];
        }
        float textHeightinVer = getHeight()/2-mPaint.descent()+(mPaint.descent()-mPaint.ascent())/2;
        canvas.drawText(mText, getWidth()/2-textWidth/widths.length,textHeightinVer,mPaint);



    }
    /**
    *设置进度条的值
    */
     public void setProgress(int progress) {
        if (progress > mMax) {
            mProgress = mMax;
        }
        this.mProgress = progress;
        //强制刷新界面,绘制新的进度,此时会调用onDraw方法
        postInvalidate();
    }

中间的圆的进度条实现方式也一样,
核心代码:

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mWidth = getWidth();
        mHeight = getHeight();
        mRadius = mWidth > mHeight ? mHeight / 2 : mWidth / 2;
        float minRadius = mRadius * 3 / 4;
        //画同心圆
        //画一个外圆
        mPaint.setColor(mBackgroundColor);
        canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mPaint);


        //画进度条   从内圆的边缘到外圆的边缘
        mPaint.setColor(mForcegroundColor);
        // double degree = mProgress * mPerProgressDegree*Math.PI/Math.toDegrees(180);
        float degree = mProgress * mPerProgressDegree;
        // Log.i("ProgressRoundBar",mWidth / 2+"-->"+degree+"---->>"+minRadius+"--->>"+mRadius+"-->>"+minRadius * Math.cos(degree)+"-->"+fromX+"--"+fromY+":::"+toX+"--"+toY);

        RectF oval = new RectF(0, 0, mRadius * 2, mRadius * 2);
        canvas.drawArc(oval, 0, mProgress * 3.6f, true, mPaint);


        //画一个内圆
        mPaint.setColor(Color.argb(255, 255, 255, 255));
        canvas.drawCircle(mWidth / 2, mHeight / 2, minRadius, mPaint);

        //在yuan内圆的中间写上进度
        mPaint.setColor(mForcegroundColor);
        String progressText = null;
        if (mProgress < 100) {
            progressText = mProgress + "%";
        } else {
            progressText = "完成";
        }
        mPaint.setTextSize(mTextSize);
        float[] widths = new float[progressText.length() - 1];
        mPaint.getTextWidths(progressText, 0, progressText.length() - 1, widths);

        float textWidth = 0;
        for (int i=0;i<widths.length;i++){
            textWidth+=widths[i];
        }
        float textHeightinVer = mHeight/2-mPaint.descent()+(mPaint.descent()-mPaint.ascent())/2;
        canvas.drawText(progressText,mRadius-textWidth/widths.length,textHeightinVer,mPaint);
    }   

要注意的是,画圆的顺序不能乱了,必须是最低下的先画,再是画上面的进度条,这是一个扇形,再画里面的内圆,最后画中间的文字。

最后一个是通过布局来实现的,一个相对布局,里面放的是一个button和一个进度条,重叠在一起,通过更新progressbar的进度来实现,这个可以保留button的特点。实现也挺简单的。
核心代码:
布局文件

 <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="16dp">

        <ProgressBar
            android:id="@+id/pb_movie_progress_id"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:max="100"
            android:progress="0"
            android:background="#999191"
            android:progressDrawable="@drawable/progress_selector"
            android:secondaryProgress="0"
            />
       <Button
           android:id="@+id/bt_registe"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
           android:textColor="@color/base_white"
            android:text="注册"
           android:background="@drawable/btn_selector"
            android:textSize="@dimen/text_commen_size" />
    </RelativeLayout>

里面的进度条的图可以自己定义

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:id="@android:id/progress">
        <clip
            android:clipOrientation="horizontal"
            android:drawable="@drawable/progress_drawable"
            android:gravity="left" />
    </item>
</layer-list>

搞定!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值