自定义进度条(水平,圆形)

MainActivity:

package com.twac.Diy_progressbar;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;

import com.twac.view.HorizontalProgressBarWithProgress;
import com.twac.view.RoundProgressBarWithProgress;

public class MainActivity extends Activity {
	private HorizontalProgressBarWithProgress mProgress;
	private RoundProgressBarWithProgress mProgress2;
	private static final int MSG_UPDATE = 0x110;

	private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			int progress = mProgress.getProgress();
			int progress2 = mProgress2.getProgress();
			mProgress.setProgress(++progress);
			mProgress2.setProgress(--progress2);
			if (progress > 100) {
				mHandler.removeMessages(MSG_UPDATE);
			}
			mHandler.sendEmptyMessageDelayed(MSG_UPDATE, 150);
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mProgress = (HorizontalProgressBarWithProgress) findViewById(R.id.progress01);
		mProgress2 = (RoundProgressBarWithProgress) findViewById(R.id.round01);
		mHandler.sendEmptyMessage(MSG_UPDATE);
	}
}

新建View包,在此包下新建两个类:

1、HorizontalProgressBarWithProgress(继承自ProgressBar)

package com.twac.view;

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.ProgressBar;

import com.twac.Diy_progressbar.R;

public class HorizontalProgressBarWithProgress extends ProgressBar {
	private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1;
	private static final int DEFAULT_TEXT_SIZE = 10;// sp
	private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR;
	private static final int DEFAULT_REACH_HEIGHT = 2;// dp
	private static final int DEFAULT_UNREACH_COLOR = 0XFFD3D6DA;
	private static final int DEFAULT_UNREACH_HEIGHT = 2;// dp
	private static final int DEFAULT_TEXT_OFFSET = 10;// dp

	protected int mTextColor = DEFAULT_TEXT_COLOR;
	protected int mTextSize = sptopx(DEFAULT_TEXT_SIZE);
	protected int mReachColor = DEFAULT_REACH_COLOR;
	protected int mReachHeight = dptopx(DEFAULT_REACH_HEIGHT);
	protected int mUnreachColor = DEFAULT_UNREACH_COLOR;
	protected int mUnreachHeight = dptopx(DEFAULT_UNREACH_HEIGHT);
	protected int mTextOffset = dptopx(DEFAULT_TEXT_OFFSET);

	protected Paint mPaint = new Paint();
	// 在onMeasure中赋值,在onDraw中应用
	private int mRealWidth;

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

	}

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

	}

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

	// 获取自定义属性
	private void obtainStyledAttrs(AttributeSet attrs) {
		TypedArray ta = getContext().obtainStyledAttributes(attrs,
				R.styleable.HorizontalProgressBarWithProgress);
		mTextColor = ta
				.getColor(
						R.styleable.HorizontalProgressBarWithProgress_progress_text_color,
						mTextColor);
		mTextSize = (int) ta
				.getDimension(
						R.styleable.HorizontalProgressBarWithProgress_progress_text_size,
						mTextSize);
		mReachColor = ta
				.getColor(
						R.styleable.HorizontalProgressBarWithProgress_progress_reach_color,
						mReachColor);
		mReachHeight = (int) ta
				.getDimension(
						R.styleable.HorizontalProgressBarWithProgress_progress_reach_height,
						mReachHeight);
		mUnreachColor = ta
				.getColor(
						R.styleable.HorizontalProgressBarWithProgress_progress_unreach_color,
						mUnreachColor);
		mUnreachHeight = (int) ta
				.getDimension(
						R.styleable.HorizontalProgressBarWithProgress_progress_unreach_height,
						mUnreachHeight);
		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) {

		int widthValue = MeasureSpec.getSize(widthMeasureSpec);

		int heightValue = measureHeight(heightMeasureSpec);
		// 确定View的宽和高
		setMeasuredDimension(widthValue, heightValue);

		mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
	}

	private int measureHeight(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());
			result = getPaddingTop()
					+ getPaddingBottom()
					+ Math.max(Math.max(mReachHeight, mUnreachHeight),
							Math.abs(textHeight));
			if (mode == MeasureSpec.AT_MOST) { // 测量值不能超过给定的size值
				result = Math.min(size, result);
			}
		}
		return result;
	}

	@Override
	protected synchronized void onDraw(Canvas canvas) {
		canvas.save();
		canvas.translate(getPaddingLeft(), getHeight() / 2);
		boolean noNeedUnReachBar = false;

		// draw ReachBar
		String text = getProgress() + "%";
		int textWidth = (int) mPaint.measureText(text);
		float radio = getProgress() * 1.0f / getMax();
		float progressX = radio * mRealWidth;
		if (progressX + textWidth > mRealWidth) {
			noNeedUnReachBar = true;
			progressX = mRealWidth - textWidth;
		}
		float endX = progressX - mTextOffset / 2;
		if (endX > 0) {
			mPaint.setColor(mReachColor);
			mPaint.setStrokeWidth(mReachHeight);
			canvas.drawLine(0, 0, endX, 0, mPaint);
		}

		// draw Text
		mPaint.setColor(mTextColor);
		int textY = (int) (-(mPaint.descent() + mPaint.ascent()) / 2);
		canvas.drawText(text, progressX, textY, mPaint);

		// draw unReachBar
		if (!noNeedUnReachBar) {
			float start = progressX + mTextOffset / 2 + textWidth;
			mPaint.setColor(mUnreachColor);
			mPaint.setStrokeWidth(mUnreachHeight);
			canvas.drawLine(start, 0, mRealWidth, 0, mPaint);
		}
		canvas.restore();
	}

	// 两个辅助方法
	protected int dptopx(int dpVal) {
		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
				dpVal, getResources().getDisplayMetrics());
	}

	protected int sptopx(int spVal) {
		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
				spVal, getResources().getDisplayMetrics());
	}
}
2、RoundProgressBarWithProgress(继承自HorizontalProgressBarWithProgress

package com.twac.view;

import com.twac.Diy_progressbar.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;

public class RoundProgressBarWithProgress extends
		HorizontalProgressBarWithProgress {

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

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

	}

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

	}

	public RoundProgressBarWithProgress(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		mReachHeight = (int) (mUnreachHeight * 3f);
		TypedArray ta = context.obtainStyledAttributes(attrs,
				R.styleable.RoundProgressBarWithProgress);

		mRadius = (int) ta.getDimension(
				R.styleable.RoundProgressBarWithProgress_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);

		// draw unReachBar
		mPaint.setColor(mUnreachColor);
		mPaint.setStrokeWidth(mUnreachHeight);
		canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
		// draw ReachBat
		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);
		// draw text
		mPaint.setColor(mTextColor);
		mPaint.setStyle(Style.FILL);
		canvas.drawText(text, mRadius - textWidth / 2, mRadius - textHeight,
				mPaint);

		canvas.restore();
	}
}

布局文件:

    <com.twac.view.HorizontalProgressBarWithProgress
        android:id="@+id/progress01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:background="#000000"
        android:padding="15dp"
        android:progress="50"
        app:progress_reach_color="#456789" />

    <com.twac.view.HorizontalProgressBarWithProgress
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="15dp"
        android:progress="98"
        app:progress_text_color="#000000" />

    <com.twac.view.RoundProgressBarWithProgress
        android:id="@+id/round01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="15dp"
        android:progress="40"
        app:radius="60dp" >
    </com.twac.view.RoundProgressBarWithProgress>

配置文件(values下新建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>
    
    <declare-styleable name="RoundProgressBarWithProgress">
        <attr name="radius" format="dimension"></attr>
    </declare-styleable>

</resources>




  • 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、付费专栏及课程。

余额充值