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

来源:互联网 发布:淘宝的拍照权限设置 编辑:程序博客网 时间:2024/05/16 11:15

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>

搞定!

0 1