Android自定义progress

本文介绍如何在Android中使用自定义属性来设置进度条的颜色,并通过Handler实现颜色动态更新的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请标明出处:http://blog.youkuaiyun.com/u013598111/article/details/49742145,本文出自:【JunTao_sun】


自定义属性

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

<span style="font-size:18px;"><resources>
    <declare-styleable name="MyView">       
        <attr name="color" format="color" />       
        <attr name="color_r" format="color" />       
    </declare-styleable>   
</resources>
</span>

<span style="font-size:18px;"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:progress="http://schemas.android.com/apk/res/com.example.customsProgress"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.example.customsProgress.ProgressView
        android:id="@+id/ProgressView1"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:padding="40dp"
        progress:color_r="#ffff0000"
        progress:color="#ff0000ff" />

    <com.example.customsProgress.ProgressView
        android:id="@+id/ProgressView2"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:padding="40dp"
        progress:color_r="#ffff0000"
        progress:color="#ff0000ff" />

    <com.example.customsProgress.ProgressView
        android:id="@+id/ProgressView3"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:padding="40dp"
        progress:color_r="#ffff0000"
        progress:color="#ff0000ff" />

    <com.example.customsProgress.ProgressView
        android:id="@+id/ProgressView4"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:padding="40dp"
        progress:color_r="#ffff0000"
        progress:color="#ff0000ff" />

</LinearLayout></span>

<span style="font-size:18px;">package com.example.customsProgress;

import java.util.Random;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.ProgressBar;

public class ProgressView extends ProgressBar {

	private static final String TAG = "ProgressView";
	private int paddingLT = 3;
	private int paddingRT = 3;
	private Paint paint;
	private Rect mbound;
	private int textWidth;
	private int textHeight;
	private int mRealWidth;
	private int heightMeasureSpe;
	private Paint rightPaint;
	private Paint textPaint;

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

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

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

		TypedArray a = context
				.obtainStyledAttributes(attrs, R.styleable.MyView);
		int progressColor = a.getColor(R.styleable.MyView_color, 0Xff0000ff);
		int progressColor_r = a
				.getColor(R.styleable.MyView_color_r, 0Xff0000ff);

		a.recycle();
		int bar = getProgress();
		textPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
		textPaint.setDither(true);
		textPaint.setColor(0xff00ff00);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		rightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		rightPaint.setColor(progressColor_r);
		paint.setStyle(Style.FILL);
		paint.setColor(progressColor);
		mbound = new Rect();
		// 测量初始高度
		measureText(bar + "");

	}

	@Override
	protected synchronized void onMeasure(int widthMeasureSpec,
			int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
		int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
		int width = MeasureSpec.getSize(widthMeasureSpec);
		int height = MeasureSpec.getSize(heightMeasureSpec);
		int w = 0;
		int h = 0;
		switch (modeWidth) {
		case MeasureSpec.EXACTLY:
			w = width;
			Log.e(TAG, "getMeasuredWidth()" + getMeasuredWidth());

			break;
		case MeasureSpec.AT_MOST:

		case MeasureSpec.UNSPECIFIED:
			w = getMeasuredWidth() + getPaddingLeft() + getPaddingRight();

			break;

		}
		// 控制MeasureSpec.AT_MOST 最大不能超出的范围
		w = modeWidth == MeasureSpec.AT_MOST ? Math.min(w, width) : w;

		switch (modeHeight) {
		case MeasureSpec.EXACTLY:
			h = height;

			break;
		case MeasureSpec.AT_MOST:

		case MeasureSpec.UNSPECIFIED:
			
			h = (int) ((-paint.ascent() + paint.descent()) + getPaddingTop() + getPaddingBottom());
			break;
		}
		h = modeHeight == MeasureSpec.AT_MOST ? Math.min(h, height) : h;

		setMeasuredDimension(w, h);

	}

	/**
	 * 测量 progress字体宽高
	 * 
	 * @param text
	 */
	private void measureText(String text) {
		textPaint.getTextBounds(text, 0, text.length(), mbound);
		textWidth = (int) textPaint.measureText(text);
		FontMetrics fm = textPaint.getFontMetrics();
		textHeight = (int) (fm.descent + fm.ascent);

	}

	private int mRight;
	private int mLeft;
	private int mRealText;
	private int mLineHeight;
	private int mTextHeight;

	@Override
	protected synchronized void onDraw(Canvas canvas) {

		super.onDraw(canvas);
		// 判断是否到达右末端
		boolean isFinishRight = false;
		canvas.save();
		// 获取进度
		int progress = getProgress();
		// 0~1 速率 *1.0f先 不然会都等于0
		float rate = progress * 1.0f / getMax();
		// 不断累加
		float start = (mRealWidth - textWidth - paddingLT * 2) * rate;
		String text = progress + "%";
		measureText(text);
		// 右边长度变化
		mRight = (int) (start + textWidth + paddingLT * 2 + getPaddingLeft());
		// 左边长度变化
		mLeft = (int) (start + getPaddingLeft());
		// text 加上两个gap的实际宽度
		mRealText = textWidth + paddingLT * 2;
		// 线的实际高度
		mLineHeight = -textHeight / 2 + getPaddingTop();
		// 字体的高度
		mTextHeight = -textHeight + getPaddingTop();

		// 判断未画的线 是不是到达 到达就把最变量start值 赋给最大值
		if (start + textWidth + paddingLT * 2 > mRealWidth) {
			start = mRealWidth;
			// 控制是否继续画
			isFinishRight = true;
		}
		if (!isFinishRight) {
			// 画右边线条
			drawRight(canvas);

		}
		// 标志 是否大于等于实际宽度
		float endX = start + textWidth + paddingLT * 2;
		if (endX >= mRealWidth) {
			// left 的最点位子,不再继续画
			start = mRealWidth - textWidth - paddingLT * 2;
			drawLeft(canvas, start);

		} else {
			// 不满足前面条件 则不断加上去
			drawLeft(canvas, start);
		}

		// 画进度  要判断endX也行  有点麻烦了
		drawText(canvas, text);

		canvas.restore();
	}

	/**
	 * @param canvas
	 * @param start
	 *            左侧进度
	 */
	private void drawRight(Canvas canvas) {

		canvas.drawLine(mLeft + mRealText, mLineHeight, mRealWidth
				+ getPaddingLeft(), mLineHeight, rightPaint);

	}

	private void drawLeft(Canvas canvas, float start) {

		canvas.drawLine(getPaddingLeft(), mLineHeight, mLeft, mLineHeight,
				paint);

	}

	private void drawText(Canvas canvas, String text) {

		canvas.drawText(text, mLeft + paddingLT, mTextHeight, textPaint);

	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {

		super.onSizeChanged(w, h, oldw, oldh);
		// 实际长度
		mRealWidth = w - getPaddingLeft() - getPaddingRight();

	}

	/**
	 * dp 2 px
	 * 
	 * @param dpVal
	 */
	protected int dp2px(int dpVal) {
		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
				dpVal, getResources().getDisplayMetrics());
	}

	/**
	 * sp 2 px
	 * 
	 * @param spVal
	 * @return
	 */
	protected int sp2px(int spVal) {
		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
				spVal, getResources().getDisplayMetrics());

	}
	String[]  colors=new String[]{"#fe9d01",
				"#fe9d01",
				"#ffbb1c",
				"#eed205",
				"#ff8c05",
				"#ff6600",
				"#ffa500"
				};
	Random random=new Random();
	//改变画笔颜色
	public void updataPaintColors(){
	this.paint.setARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));
	this.textPaint.setARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));	
	this.rightPaint.setARGB(255, random.nextInt(255), random.nextInt(255), random.nextInt(255));
		
		
//	    int i=random.nextInt(colors.length);
//		this.paint.setColor(Color.parseColor(colors[i]));
//		int j=	random.nextInt(colors.length);
//		this.rightPaint.setColor(Color.parseColor(colors[j]));
	}

}
</span>

<span style="font-size:18px;">package com.example.customsProgress;

import android.R.integer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.renderscript.Sampler.Value;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.ProgressBar;

public class MainActivity extends Activity {
	private static final int SEND_PROGRESS1 = 1;
	private static final int SEND_PROGRESS2 = 2;
	private static final int SEND_PROGRESS3 = 3;
	private static final int SEND_PROGRESS4 = 4;
	private ProgressView view1, view2, view3, view4;
	private Handler handle = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SEND_PROGRESS1:
				int progress1 = view1.getProgress();
				view1.updataPaintColors();
				view1.setProgress(++progress1);

				if (progress1 <= 100) {
					handle.removeMessages(SEND_PROGRESS1);
				}
				handle.sendEmptyMessageDelayed(SEND_PROGRESS1, 40);
				break;
			case SEND_PROGRESS2:
				int progress2 = view2.getProgress();

				view2.updataPaintColors();
				view2.setProgress(++progress2);

				if (progress2 <= 100) {
					handle.removeMessages(SEND_PROGRESS2);
				}
				handle.sendEmptyMessageDelayed(SEND_PROGRESS2, 30);
				break;
			case SEND_PROGRESS3:
				int progress3 = view3.getProgress();
				view3.updataPaintColors();

				view3.setProgress(++progress3);

				if (progress3 <= 100) {
					handle.removeMessages(SEND_PROGRESS3);
				}
				handle.sendEmptyMessageDelayed(SEND_PROGRESS3, 25);
				break;
			case SEND_PROGRESS4:
				int progress4 = view4.getProgress();
				view4.updataPaintColors();

				view4.setProgress(++progress4);

				if (progress4 <= 100) {
					handle.removeMessages(SEND_PROGRESS4);
				}
				handle.sendEmptyMessageDelayed(SEND_PROGRESS4, 45);
				break;

			}
			;

		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		view1 = (ProgressView) this.findViewById(R.id.ProgressView1);
		view2 = (ProgressView) this.findViewById(R.id.ProgressView2);
		view3 = (ProgressView) this.findViewById(R.id.ProgressView3);
		view4 = (ProgressView) this.findViewById(R.id.ProgressView4);
		Message ms = handle.obtainMessage();
		ms.what = SEND_PROGRESS1;
		handle.sendMessage(ms);

		Message ms1 = handle.obtainMessage();
		ms1.what = SEND_PROGRESS2;
		handle.sendMessage(ms1);

		Message ms2 = handle.obtainMessage();
		ms2.what = SEND_PROGRESS3;
		handle.sendMessage(ms2);

		Message ms3 = handle.obtainMessage();
		ms3.what = SEND_PROGRESS4;
		handle.sendMessage(ms3);

	}

}
</span>
好好学习,天天向上。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值