您的位置:首页 > 移动开发 > Android开发

Android 自定义ProgressBar

2016-10-31 22:39 281 查看
效果如图



调用代码如下

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

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: