Android 自定义ProgressBar

效果如图

这里写图片描述

调用代码如下

package com.example.MyProgressbar;

import com.ws.progressView.HorizontalProgress;
import com.ws.progressView.RoundProgress;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

public class MainActivity extends Activity {

    private HorizontalProgress mHprogress;
    private RoundProgress mRoundProgress;
    //更新进度条
    public static final int UPDATE_MSG=0X110;
    private Handler mHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {

            int progress=mHprogress.getProgress();
            mHprogress.setProgress(++progress);

            int roundProgress=mRoundProgress.getProgress();
            mRoundProgress.setProgress(++roundProgress);

            if(progress>=100){
                mHandler.removeMessages(UPDATE_MSG);
            }else{
                mHandler.sendEmptyMessageDelayed(UPDATE_MSG, 100);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

      mHprogress=(HorizontalProgress) findViewById(R.id.progress_1);
      mRoundProgress=(RoundProgress) findViewById(R.id.progress_4);


      mHandler.sendEmptyMessage(UPDATE_MSG);
    }



}
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:ws="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">



    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

        <com.ws.progressView.HorizontalProgress
            android:id="@+id/progress_1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:progress="0"
            android:padding="5dp"
            ws:progress_unreach_color="#44ff0000"
            android:layout_marginTop="30dp"
            />

          <com.ws.progressView.HorizontalProgress
            android:id="@+id/progress_2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:progress="30"
            android:padding="15dp"
            android:layout_marginTop="30dp"
            ws:progress_text_color="#44ff0000"
            ws:progress_unreach_color="#ffffff"

            />

          <com.ws.progressView.RoundProgress
            android:id="@+id/progress_3"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:progress="30"
            android:padding="15dp"
            android:layout_marginTop="30dp"         
            ws:progress_unreach_color="#44ff0000"
            ws:radius="20dp"
            />
            <com.ws.progressView.RoundProgress
            android:id="@+id/progress_4"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:progress="0"
            android:padding="15dp"
            android:layout_marginTop="30dp"
            ws:progress_text_color="#44ff0000"
            ws:progress_unreach_color="#000000"
            ws:progress_text_size="20sp"
            ws:radius="60dp"
            />

        </LinearLayout>


</ScrollView>

下面看代码实现

自定义View第一步 定义属性

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


         <declare-styleable name="HorizontalProgress" >     
          <attr name="progress_unreach_color"  format="color"></attr>
          <attr name="progress_unreach_height" format="dimension"></attr>
          <attr name="progress_reach_color" format="color"></attr>
          <attr name="progress_reach_height" format="dimension"></attr>
          <attr name="progress_text_color" format="color"></attr>
          <attr name="progress_text_size" format="dimension"></attr>
          <attr name="progress_text_offset" format="dimension"></attr>
         </declare-styleable>


         <declare-styleable name="RoundProgress">
              <attr name="radius" format="dimension"></attr>
         </declare-styleable>

</resources>
package com.ws.progressView;

import com.example.MyProgressbar.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.webkit.WebSettings.TextSize;
import android.widget.ProgressBar;

public class HorizontalProgress extends ProgressBar {

    public static final int DEFAULT_TEXT_SIZE=10;//sp
    public static final int DEFAULT_TEXT_COLOR=0XFFFC00D1;
    public static final int DEFAULT_COLOR_UNREACH=0XFFD3D6DA;
    public static final int DEFAULT_HEIGHT_UNREACH=2;//dp
    public static final int DEFAULT_COLOR_REACH=DEFAULT_TEXT_COLOR;
    public static final int DEFAULT_HEIGHT_RRACH=2;//dp
    public static final int DEFAULT_TEXT_OFFSET=10;//dp     

    protected int mTextSize=sp2px(DEFAULT_TEXT_SIZE);
    protected int mTextColor=DEFAULT_TEXT_COLOR;
    protected int mUnReachColor=DEFAULT_COLOR_UNREACH;
    protected int mUnReachHeight=dp2px(DEFAULT_HEIGHT_UNREACH);
    protected int mReachColor=DEFAULT_COLOR_REACH;
    protected int mReachHeight=dp2px(DEFAULT_HEIGHT_RRACH);
    protected int mTextOffset=dp2px(DEFAULT_TEXT_OFFSET);//空隙的长度

    protected Paint mPaint=new Paint();
    protected int mRealWidth;



    public HorizontalProgress(Context context) {
        this(context,null);

    }
    public HorizontalProgress(Context context, AttributeSet attrs) {
        this(context, attrs,0);

    }   
    public HorizontalProgress(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        abtainStyledAttrs(attrs);

    }
    /**
     * 获取自定义属性
     * @param attrs
     */
    private void abtainStyledAttrs(AttributeSet attrs) {
        TypedArray ta=getContext().obtainStyledAttributes(attrs, R.styleable.HorizontalProgress);

        mTextSize=(int) ta.getDimension(R.styleable.HorizontalProgress_progress_text_size, mTextSize);
        mTextColor=ta.getColor(R.styleable.HorizontalProgress_progress_text_color, mTextColor);
        mUnReachColor=ta.getColor(R.styleable.HorizontalProgress_progress_unreach_color, mUnReachColor);
        mUnReachHeight=(int) ta.getDimension(R.styleable.HorizontalProgress_progress_unreach_height, mUnReachHeight);
        mReachColor=ta.getColor(R.styleable.HorizontalProgress_progress_reach_color, mReachColor);
        mReachHeight=(int) ta.getDimension(R.styleable.HorizontalProgress_progress_reach_height, mReachHeight);
        mTextOffset=(int) ta.getDimension(R.styleable.HorizontalProgress_progress_text_offset, mTextOffset);

        ta.recycle();

        mPaint.setTextSize(mTextSize);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec,
            int heightMeasureSpec) {

        //int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        int widthVal=MeasureSpec.getSize(widthMeasureSpec); //宽度直接让用户定,不能自适应
        int height=measureHeight(heightMeasureSpec);        
        setMeasuredDimension(widthVal, height);
        //获得控件的真实高度
        mRealWidth=getMeasuredWidth()-getPaddingLeft()-getPaddingRight();
    }


    private int measureHeight(int heightMeasureSpec) {
       int result=0;
       int model=MeasureSpec.getMode(heightMeasureSpec);
       int size=MeasureSpec.getSize(heightMeasureSpec);

       if(model==MeasureSpec.EXACTLY){
           result=size;
       }else{
           int textHeight=(int) (mPaint.descent()-mPaint.ascent());
           result=getPaddingBottom()+getPaddingTop()+Math.max(Math.max(mUnReachHeight, mReachHeight), Math.abs(textHeight));

           //高度不能大于给定的高度
           if(model==MeasureSpec.AT_MOST){
               result=Math.min(result, size);
           }
       }

        return result;
    }


    @Override
    protected synchronized void onDraw(Canvas canvas) {

        canvas.save();
        canvas.translate(getPaddingLeft(), getHeight()/2);//移动画布的位置

        Boolean noNeedUnreach=false;

        String text=getProgress()+"%";
        int textWidth=(int) mPaint.measureText(text);
        float radio=getProgress()*1.0f/getMax();//百分比
        float ProgressX=radio*mRealWidth;//已经过的进度值
        if((ProgressX+textWidth)>mRealWidth){
            ProgressX=mRealWidth-textWidth;
            noNeedUnreach=true;
        }

        //绘制reachbar
        float endX=ProgressX-mTextOffset/2;
        if(endX>0){
            mPaint.setColor(mReachColor);
            mPaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(0, 0, endX, 0, mPaint);
        }
        //绘制文字
        mPaint.setColor(mTextColor);
        int y=(int) (-(mPaint.descent()+mPaint.ascent())/2);
        canvas.drawText(text, ProgressX, y, mPaint);
        //绘制unReachbar
        if(!noNeedUnreach){
            float start=ProgressX+textWidth+mTextOffset/2;
            mPaint.setColor(mUnReachColor);
            mPaint.setStrokeWidth(mUnReachHeight);
            canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
        }

        canvas.restore();
    }


    protected int dp2px(int dp){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());        
    }
    protected int sp2px(int sp){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
    }

}
package com.ws.progressView;

import com.example.MyProgressbar.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.ProgressBar;

public class RoundProgress extends HorizontalProgress {

    private int mRadius=dp2px(30);
    private int mMaxPaintWidth;

    public RoundProgress(Context context) {   
        this(context,null);
        // TODO Auto-generated constructor stub
    }

    public RoundProgress(Context context, AttributeSet attrs) {
        this(context, attrs,0);
        // TODO Auto-generated constructor stub    
    }

    public RoundProgress(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mReachHeight=(int) (mUnReachHeight*2.5);

        TypedArray ta=context.obtainStyledAttributes(attrs,R.styleable.RoundProgress);
        mRadius=(int) ta.getDimension(R.styleable.RoundProgress_radius, mRadius);
        ta.recycle();

        mPaint.setStyle(Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStrokeCap(Cap.ROUND);

    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec,
            int heightMeasureSpec) {

        mMaxPaintWidth=Math.max(mReachHeight, mUnReachHeight);
        int expect=mRadius*2+mMaxPaintWidth+getPaddingLeft()+getPaddingRight();

        int width=resolveSize(expect, widthMeasureSpec);
        int height=resolveSize(expect, heightMeasureSpec);

        int realWidth=Math.min(width, height);
        mRadius=(realWidth-getPaddingLeft()-getPaddingRight()-mMaxPaintWidth)/2;


        setMeasuredDimension(realWidth, realWidth);
    }

@Override
   protected synchronized void onDraw(Canvas canvas) {
     String text=getProgress()+"%";
     float textWidth=mPaint.measureText(text);
     float textHeight=(mPaint.descent()+mPaint.ascent())/2;

     canvas.save();
     canvas.translate(getPaddingLeft()+mMaxPaintWidth/2, getPaddingTop()+mMaxPaintWidth/2);
     mPaint.setStyle(Style.STROKE);

     //绘制unReact
     mPaint.setColor(mUnReachColor);
     mPaint.setStrokeWidth(mUnReachHeight);
     canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
     //绘制react
     mPaint.setColor(mReachColor);
     mPaint.setStrokeWidth(mReachHeight);
    float sweepAngle=getProgress()*1.0f/getMax()*360;
    canvas.drawArc(new RectF(0,0,mRadius*2,mRadius*2), 0, sweepAngle, false, mPaint);
    //绘制文字
    mPaint.setColor(mTextColor);
    mPaint.setStyle(Style.FILL);
    canvas.drawText(text, mRadius-textWidth/2, mRadius-textHeight/2, mPaint);

     canvas.restore();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值