自定义进度条HorizontalProgressBarWithProgress

这是一个自定义ProgressBar的案例,自定义水平进度条,运行效果如图:



要定义这个水平进度条需要有如下的属性:即attrs.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <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 name="HorizontalProgressBarWithProgress">
        
        <attr name="progress_unreach_color" ></attr>
	    <attr name="progress_unreach_height" ></attr>
	    <attr name="progress_reach_color" ></attr>
	    <attr name="progress_reach_height" ></attr>
	    <attr name="progress_text_color" ></attr>
	    <attr name="progress_text_size" ></attr>
	    <attr name="progress_text_offset" ></attr>
        
    </declare-styleable>
    
</resources>

HorizontalProgressBarWithProgress.java的代码如下:


</pre><pre name="code" class="java">package com.tommy.view;

import com.tommy.progressbardemo.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.widget.BaseAdapter;
import android.widget.ProgressBar;

/**
 * 自定义一个水平的附带进度的ProgressBar
 * @author Tommy
 *
 */


public class HorizontalProgressBarWithProgress extends ProgressBar{

	private static final int DEFAULT_TEXT_SIZE = 10;//sp
	private static final int DEFAULT_TEXT_COLOR = 0xFFFC00D1;
	private static final int DEFAULT_UNREACH_COLOR = 0xFFD3D6DA;
	private static final int DEFAULT_REACH_COLOR = 0xFFFC00D1;
	private static final int DEFAULT_UNREACH_HEIGHT = 2;//dp
	private static final int DEFAULT_REACH_HEIGHT = 2;//dp
	private static final int DEFAULT_TEXT_OFFSET = 10;//dp
	
	private int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
	private int mTextColor = DEFAULT_TEXT_COLOR;
	private int mUnReachColor = DEFAULT_UNREACH_COLOR;
	private int mUnReachHeight = dp2px(DEFAULT_UNREACH_HEIGHT);
	private int mReachColor = DEFAULT_REACH_COLOR;
	private int mReachHeight = dp2px(DEFAULT_REACH_HEIGHT);
	private int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);
	
	
	private Paint mPaint = new Paint();
	
	/**
	 * 该值是ProgressBar的真正的值,是getWidth - padding的值,可能在onMeasure中初始化,
	 * 在onDraw中使用。
	 */
	private int mRealWidth = 0;
	
	
	
	public HorizontalProgressBarWithProgress(Context context,
			AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		
		obtainStyledAttrs(attrs);
		
	}
	
	public HorizontalProgressBarWithProgress(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}

	public HorizontalProgressBarWithProgress(Context context) {
		this(context,null);
	}
	
	/**
	 * 获取自定义属性的值
	 * @param attrs
	 */
	private void obtainStyledAttrs(AttributeSet attrs) {
		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();
		
		mPaint.setTextSize(mTextSize);
	}
	
	
	@Override
	protected synchronized void onMeasure(int widthMeasureSpec,
			int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		
		//int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthVal = MeasureSpec.getSize(widthMeasureSpec);
		
		int heigthVal = measureHeight(heightMeasureSpec);
		
		setMeasuredDimension(widthVal, heigthVal);
		
		mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
		
		
	}
	
	
	
	/**
	 * 测量高度
	 * @param heightMeasureSpec
	 * @return
	 */
	private int measureHeight(int heightMeasureSpec) {
		
		int result = 0;
		
		int mode = MeasureSpec.getMode(heightMeasureSpec);
		int size = MeasureSpec.getSize(heightMeasureSpec);
		
		//MeasureSpec.EXACTLY这个值意思是说,在布局中我们用到了一个精确的值,比如wrap_content,200dp这一类值。
		if(mode == MeasureSpec.EXACTLY){
			result = size;
		}else {
			int textHeight = (int) (mPaint.descent() - mPaint.ascent());
			result = getPaddingBottom() + getPaddingTop() + 
					Math.max(Math.max(mReachHeight, mUnReachHeight), Math.abs(textHeight));
			
			if(mode == MeasureSpec.AT_MOST){
				result = Math.min(result, size);
				
			}
		}
		
		
		return result;
	}
	
	
	@Override
	protected synchronized void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		canvas.save();
		
		canvas.translate(getPaddingLeft(), getHeight()/2);
		
		boolean noNeedUnReach = false;
		//draw reachBar
		String text = getProgress() + "%";
		int textWidth = (int) mPaint.measureText(text);
		float radio = getProgress() * 1.0F/getMax();
		
		float progressX = radio * mRealWidth;
		
		if(progressX > (mRealWidth - textWidth)){
			progressX = mRealWidth - textWidth;
			
			noNeedUnReach = true;
		}
		float endX = progressX - mTextOffset / 2;
		if(endX > 0){
			mPaint.setColor(mReachColor);
			mPaint.setStrokeWidth(mReachHeight);
//			if(noNeedUnReach){
//				canvas.drawLine(0, 0, endX - textWidth, 0, mPaint);
//			}
			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 unReachBar
		if(!noNeedUnReach){
			float start = progressX + textWidth +  mTextOffset/2;
			mPaint.setColor(mUnReachColor);
			mPaint.setStrokeWidth(mUnReachHeight);
			canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
			
		}
		
		canvas.restore();
	}

	/**
	 * 用于将dp转化为px的工具方法。
	 * @param dpVal
	 * @return
	 */
	private int dp2px(int dpVal){
		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, 
				getResources().getDisplayMetrics());
	}
	
	/**
	 * 用于将dp转化为px的工具方法。
	 * @param spVal
	 * @return
	 */
	private int sp2px(int spVal){
		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal,
				getResources().getDisplayMetrics());
		
	}

	
}


软后在activity_main.xml中去引用这个自定义控件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:tommy="http://schemas.android.com/apk/res/com.tommy.progressbardemo"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
	<ScrollView 
	    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.tommy.view.HorizontalProgressBarWithProgress 
	            android:layout_width="match_parent"
	            android:layout_height="wrap_content"
	            android:background="#44ff0000"
	            android:progress="50"
	            android:padding="15dp"
	            android:layout_marginTop="30dp"
	            />
	         <com.tommy.view.HorizontalProgressBarWithProgress 
	            android:layout_width="match_parent"
	            android:layout_height="wrap_content"
	            android:background="#44ff0000"
	            android:layout_marginTop="30dp"
	            android:progress="100"
	            android:padding="15dp"
	            tommy:progress_text_color="#ff000000"
	            tommy:progress_unreach_color="#ff000000"
	            />
	         <com.tommy.view.HorizontalProgressBarWithProgress 
	            android:layout_width="match_parent"
	            android:layout_height="wrap_content"
	            android:background="#44ff0000"
	            android:layout_marginTop="30dp"
	            android:progress="30"
	            android:padding="15dp"
	            tommy:progress_text_color="#ff000000"
	            tommy:progress_unreach_color="#ff000000"
	            />
	    </LinearLayout>
	</ScrollView>
    
    
	
</LinearLayout>

MainActivity代码在这里就省略了。


这是自定义圆形进度条的一个案例:http://sumile.cn/archives/1523.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于 Android 自定义进度条控件的实现,我可以为您提供一些思路和示例代码。 首先,我们需要继承自 View 或者 ProgressBar,然后在 onDraw 方法中实现自己的绘制逻辑。具体来说,需要绘制背景、进度条和文本等内容。 示例代码如下: ```java public class CustomProgressBar extends ProgressBar { private Paint mPaint; private String mText; private Rect mRect; public CustomProgressBar(Context context) { super(context); init(); } public CustomProgressBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mRect = new Rect(); } @Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制背景 mPaint.setColor(Color.GRAY); mPaint.setStyle(Paint.Style.FILL); canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint); // 绘制进度条 mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.FILL); float progress = getProgress() * 1.0f / getMax(); canvas.drawRect(0, 0, getWidth() * progress, getHeight(), mPaint); // 绘制文本 mPaint.setColor(Color.WHITE); mPaint.setTextSize(24); mText = getProgress() + "%"; mPaint.getTextBounds(mText, 0, mText.length(), mRect); float x = getWidth() / 2f - mRect.centerX(); float y = getHeight() / 2f - mRect.centerY(); canvas.drawText(mText, x, y, mPaint); } } ``` 这个自定义控件实现了一个简单的水平进度条,包括了背景、进度条和文本三个部分。当然,您可以根据自己的需求进行更改和扩展。 希望这个示例代码能够帮助到您,如果您还有其他问题,欢迎继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值