Android 自定义进度条

本文介绍了如何在Android中自定义进度条控件,包括声明和获取自定义属性、控件的测量及绘制方法,详细步骤助你实现个性化进度条。
摘要由CSDN通过智能技术生成

如何自定义控件
1: 自定义属性的声明与获取,建attrs文件
这里写图片描述

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

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

    </declare-styleable>

</resources>

在main-java-包下边建立HorizontalProgressbarWithProgress.java文件
并继承ProgressBar,重写方法

public class HorizontalProgressbarWithProgress extends ProgressBar{
}

通过getContext().obtainStyledAttributes获取自定义属性,存放至TypedArray

 TypedArray ta=getContext().obtainStyledAttributes(attrs, R.styleable.HorizontalProgressbarWithProgress);

        mTextSize=(int)ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_text_size,mTextSize);
          mTextColor=ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_text_color,mTextColor);
          mUnReachColor=ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_unreach_color,mUnReachColor);
          mUnReachHeight=(int)ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_unreach_height,mUnReachHeight);
          mReachColor=ta.getColor(R.styleable.HorizontalProgressbarWithProgress_progress_reach_color,mReachColor);
          mReachHeight=(int)ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_reach_height,mReachHeight);
          mTextOffset=(int)ta.getDimension(R.styleable.HorizontalProgressbarWithProgress_progress_text_offset,mTextOffset);
  ta.recycle();

2: 测量onMeasure

 @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        int widthVal=MeasureSpec.getSize(widthMeasureSpec);

        int height=measureHeitht(heightMeasureSpec);//获取高度(分情况)

        setMeasuredDimension(widthVal,height);//确定view的宽和高
        mRealWidth=getMeasuredWidth()-getPaddingLeft()-getPaddingRight();

    }

    private int measureHeitht(int heightMeasureSpec) {
        int result=0;
        int mode=MeasureSpec.getMode(heightMeasureSpec);
        int size=MeasureSpec.getSize(heightMeasureSpec);
        if(mode==MeasureSpec.EXACTLY){//精确值(一共三种情况)
            result=size;
        }else{
           int textHeight=(int)(mPaint.descent()-mPaint.ascent());//获得文字的高度
            //getPaddingBottom()+getPaddingTop()是必须要加的,之后测量reach,UNreach和文字的最大值
            result=getPaddingBottom()+getPaddingTop()+
                    Math.max(Math.max(mReachHeight,mUnReachHeight),Math.abs(textHeight));
           if(mode==MeasureSpec.AT_MOST){//该模式,测量的值不能超过给定的size
              result=Math.min(result,size);
           }

        }
        return result ;
    }

3: 绘制onDraw

@Override
    protected synchronized void onDraw(Canvas canvas) {
        boolean noNeedUnReach=false;//不显示
//注:canvas.save();和canvas.restore();是两个相互匹配出现,操作之前调用canvas.save()来保存画布当前的状态,当操作之后取出之前保存过的状态
        canvas.save();//保存画布的状态
        canvas.translate(getPaddingLeft(),getHeight()/2);//将坐标移动到左边中间

        //draw reach
        float radio=getProgress()*1.0f/getMax();//得到绘制长度占总长度百分比
        String text=getProgress()+"%";
        int textWidth=(int)mPaint.measureText(text);//测量文字的宽度
        float progressX=radio*mRealWidth;
        if(progressX+textWidth>mRealWidth){//如果reach和文字的长度的和大于总长度
            progressX=mRealWidth-textWidth;
            noNeedUnReach=true;
        }
        float endX=radio*mRealWidth-mTextOffset/2;//结束位置的坐标
        if(endX>0){
            mPaint.setColor(mReachColor);
            mPaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(0,0,endX,0,mPaint);
        }
//draw text
        mPaint.setColor(mTextColor);
        int y=(int)-((mPaint.descent()+mPaint.ascent())/2);
        canvas.drawText(text,progressX,y,mPaint);
//draw unreach
        if(!noNeedUnReach){//为true,显示
            float start=progressX+mTextOffset/2+textWidth;
            mPaint.setColor(mUnReachColor);
            mPaint.setStrokeWidth(mUnReachHeight);
            canvas.drawLine(start,0,mRealWidth,0,mPaint);


        }
        canvas.restore();//取出保存的状态
    }

到此,自定义控件设计完成
在MainActivity.java

public class MainActivity extends Activity {
    private  HorizontalProgressbarWithProgress mHProgress;
    private  static final int MSG_UPDATE=0X110;
    private Handler mHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            int progress=mHProgress.getProgress();
            mHProgress.setProgress(++progress);
            if(progress>=100){
                mHandler.removeMessages(MSG_UPDATE);
            }
            mHandler.sendEmptyMessageDelayed(MSG_UPDATE,100);
        }
    };
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHProgress=(HorizontalProgressbarWithProgress)findViewById(R.id.id_progress01);
mHandler.sendEmptyMessage(MSG_UPDATE);
    }

}

在xml中布局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:hyman="http://schemas.android.com/apk/res-auto"
    tools:context="com.example.administrator.progressbartest.MainActivity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

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

        <com.example.administrator.progressbartest.HorizontalProgressbarWithProgress
            android:id="@+id/id_progress01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:progress="0"
            hyman:progress_unreach_color="#ff000000"
            android:padding="15dp"
            hyman:progress_reach_color="@color/colorAccent"
            android:layout_marginTop="30dp"
            />

        <com.example.administrator.progressbartest.HorizontalProgressbarWithProgress
            android:id="@+id/id_progress02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            hyman:progress_reach_color="#99ffff00"
            android:progress="20"
            android:padding="5dp"
            hyman:progress_unreach_color="#77ffff00"
            android:layout_marginTop="60dp"
            />

    </LinearLayout>

</ScrollView>

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值