Android 自定义进度条,

最近工作繁忙,一直都埋头在工作中,也不知这么热心工作究竟是为了什么,不知不觉的,到今天才晓得夏天已经来了。天气热,心也热。

网络上出个牛人,辞职信上写着:世界那么大,我想去看看。由衷的佩服她的勇气,我也想去看看这大千世界,可惜我们总是身不由己,有太多的放不下,或许哪天放下了,我也出去走走。

之前一直以为罗永浩是个逗比,直到前两天看了他几期演讲,才发现逗比一直是我。他有句话我很欣赏,这里也分享给大家:在什么样的年纪,就做什么样的事情,怎么能在每个阶段都做错呢!PS:该玩的年纪玩,该谈恋爱的年纪谈恋爱,该成家立业担起一个家的年纪就要挺起胸膛,总不能错过玩的年纪,错过谈恋爱的年纪,而成家后却又搞外遇,怎么能在每个阶段都做错呢?

在我有那个勇气也在辞职信上写着“世界那么大,我也想去看看!”之前,还是要把眼前的事情做完,现在开始规划。

正文

Android进度条是很多人都接触到的,然而面对各种各样的需求时,原生的很多东西都满足不了我们的需要,在各种压迫下,大家都选择自定义来解决问题。今天给大家介绍一下自定义进度条。

提到自定义,这曾经一直是使我头疼的问题,看过很多大牛的源码之后,发现一个道理,有些代码不应该记住,而有些代码也不应该忘记。所以我决定,今天的博客里给大家分享方法。(其实是代码逻辑实在是太糟糕了,我写过后回头看的时候都不知道自己为什么那么写,而且还必须那么写,哈哈。)

首先我们要知道自定义View中那些方法是我们需要用到的。

构造方法:

构造方法是必不可少的,所有在View对象一出来就需要存在的都要在这里初始化。这里就不多说了。

onDraw

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
	}

onDraw方法用来绘制我们需要的东西,任何东西,bitmap、线、矩形、路径、等等。

onSizeChanged

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		// TODO Auto-generated method stub
		super.onSizeChanged(w, h, oldw, oldh);
	}

这里通常处理跟控件宽高有关的数值。

以上这三个,就可以完成常规的自定义组件,往往我们的业务逻辑上,需要加上很多事件,比如onclick,ontouch等。用到这些事件监听时,通常需要invalidate方法来在需要的时候刷新界面。

需要注意的是,每个方法的执行顺序,建议大家自己用log日志实验一下。方便记忆。

接下来开始贴代码,现在大多数需求都是圆角进度条,这里也以此为例。

onDraw方法是用来绘制任何我们需要的东西的,所以进度条也在此绘制,我将进度条矩形抽取出一个方法,方便复用。

	/**
	 * 绘制矩形
	 *
	 * @param canvas
	 * @param paint
	 * @param left
	 *            左
	 * @param top
	 *            上
	 * @param right
	 *            右
	 * @param bottom
	 *            下
	 */
	private void drawRect(Canvas canvas, Paint paint, float left, float top, float right, float bottom) {
		RectF rectF = new RectF(left, top, right, bottom);
		if (isRoundRect) {
			canvas.drawRoundRect(rectF, mRadius, mRadius, paint);
		} else {
			canvas.drawRect(rectF, paint);
		}
	}

这个方法,我们就可以用任何颜色的画笔,在任何位置绘制矩形。

好了,我们的自定义进度条讲完了。

但是这也就是纯粹的进度条了,需要对应的set和get方法来设置和获取值。set后,记得调用invalidate方法来重绘界面。

我的进度条有拖拽功能,先绘制拖拽的圆圈。

	/**
	 * 绘制拖动点
	 * @param canvas
	 */
	private void drawDragClick(Canvas canvas) {
		mDragClickPaint.setColor(Color.BLACK);
		RectF oval = new RectF(mAboveProgressWidth - mDragClickPaintRadius, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius, mAboveProgressWidth + mDragClickPaintRadius, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius);
		canvas.drawOval(oval, mDragClickPaint);
		mDragClickPaint.setColor(Color.WHITE);
		RectF oval2 = new RectF(mAboveProgressWidth - mDragClickPaintRadius + 1, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius + 1, mAboveProgressWidth + mDragClickPaintRadius - 1, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius - 1);
		canvas.drawOval(oval2, mDragClickPaint);
	}

既然是拖拽,肯定是ontouch方法来处理业务。

	private boolean isActionUp;
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		int code = event.getAction();
//		Log.i("progress", "onTouch"+mAboveProgressWidth);
		switch (code) {
		case MotionEvent.ACTION_DOWN:
			isActionUp = false;
			setOnTouchInit(event);
			break;
		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			isActionUp = true;
			setOnTouchInit(event);
			break;
		case MotionEvent.ACTION_MOVE:
			isActionUp = false;
			setOnTouchInit(event);
			break;
		}

		return true;
	}
	/**
	 * 触摸时设置边界
	 */
	private void setOnTouchInit(MotionEvent event){
		if (isTransfer) {
			if (event.getX() < mDragClickPaintRadius) {
				mAboveProgressWidth = mDragClickPaintRadius;
			}else if (event.getX() > mCenterProgressWidth) {
				mAboveProgressWidth = mCenterProgressWidth;
//				Log.i("progress", "onTouch"+mAboveProgressWidth + "***" + mCenterProgressWidth);
			}else {
				mAboveProgressWidth = event.getX();
			}
		}else {
			if (event.getX() < mDragClickPaintRadius) {
				mAboveProgressWidth = mDragClickPaintRadius;
			}else if (event.getX() > mWidth - mDragClickPaintRadius) {
				mAboveProgressWidth = mWidth - mDragClickPaintRadius;
			}else {
				mAboveProgressWidth = event.getX();
			}
		}
		mFirstValue = mMaxValue *( mAboveProgressWidth - mDragClickPaintRadius) / mDrawScaleWidth;
		if (mDragListener != null && isActionUp) {
			mDragListener.onDrag(this, getmFirstValue());
		}
		invalidate();
	}

这样,就能实现拖拽的效果了,当然功能不止这些,放开脑洞,当基础条件具备时,一切都可以set和get。

贴上全部的控件代码

package com.qiyuan.activity.view;

import java.util.Collections;
import java.util.List;

import android.R.integer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.View.OnClickListener;

/**
 * 可以拖动的进度条
 *
 * @author lizhipeng
 *
 */
public class CanDragProgressView extends View implements OnTouchListener,OnClickListener{

	private int mWidth, mHeight;// 整个的宽和高
	private long mDrawScaleWidth;// 画刻度时用的宽度(两边减去拖动点半径的宽度)
	private int mScaleHeight = 10;// 刻度线的高度
	private int mProgressHeight;// 进度条的相对高度
	private float mProgressRealHeight = 40;//进度条真实高度
	private int mAverageScaleNumber = 10;// 设置均分刻度的个数(多少个单位)
	private int mScaleLineWidth, mScalerLineHeight;// 刻度线宽高
	private int mRadius;// 进度条圆角半径
	private float mDragClickPaintRadius;// 拖动点半径
	private float mStartX;
	private float mStartY = 5;
	private float mFirstValue;//显示在拖动条上的值
	private float mSecondValue;//第二个值
	private float mBgProgressWidth, mCenterProgressWidth, mAboveProgressWidth;// 背景、中间、上层进度条宽度(长度)
	private Paint mBackgroundPaint, mCenterPaint, mAbovePaint, mScalePaint, mDragClickPaint;// 背景画笔,中间层画笔,上层画笔、刻度线、拖动点

	private boolean isRoundRect = true;// 是否是圆角矩形
	private boolean isAverageScale = true;// 是否均分刻度,如果不均分刻度,需要用设置刻度的集合mScaleList
	private boolean isDrawScaleUp = false;// 绘制刻度在进度条上或者下,默认是下
	private boolean isDrawScale = true;// 是否绘制刻度
	private boolean isDrawCenterScale = false;// 是否绘制中间部分的刻度
	private boolean isTransfer = false;// 是否是Transfer界面

	private float mMaxValue;//最大值

	private List<Float> mScaleList;

	private DragListener mDragListener;//滑动监听
	public interface DragListener{
		public void onDrag(CanDragProgressView view,float value);
	}

	public DragListener getmDragListener() {
		return mDragListener;
	}

	public void setmDragListener(DragListener mDragListener) {
		this.mDragListener = mDragListener;
	}

	public boolean isTransfer() {
		return isTransfer;
	}

	public void setTransfer(boolean isTransfer) {
		this.isTransfer = isTransfer;
		invalidate();
	}

	public boolean isDrawCenterScale() {
		return isDrawCenterScale;
	}

	public void setDrawCenterScale(boolean isDrawCenterScale) {
		this.isDrawCenterScale = isDrawCenterScale;
		invalidate();
	}

	public float getmSecondValue() {
		return mSecondValue;
	}

	public void setmSecondValue(float mSecondValue) {
		this.mSecondValue = mSecondValue;
		invalidate();
	}

	public float getmFirstValue() {
		return Float.parseFloat(String.format("%1.2f", mFirstValue));
	}

	public void setmFirstValue(float mValue) {
		this.mFirstValue = mValue;
		invalidate();
	}

	public List<Float> getmScaleList() {
		return mScaleList;
	}

	public void setmScaleList(List<Float> list) {
		Collections.sort(list);
		this.mScaleList = list;
		invalidate();
	}

	public float getmProgressRealHeight() {
		return mProgressRealHeight;
	}

	public void setmProgressRealHeight(float mProgressRealHeight) {
		this.mProgressRealHeight = mProgressRealHeight;
		invalidate();
	}

	public void setmScaleHeight(int mScaleHeight) {
		this.mScaleHeight = mScaleHeight;
		invalidate();
	}

	public boolean isDrowScaleUp() {
		return isDrawScaleUp;
	}

	public void setDrowScaleUp(boolean isDrowScaleUp) {
		this.isDrawScaleUp = isDrowScaleUp;
		mStartY = mScaleHeight + getFontHeight(mScalePaint) + 5;
		invalidate();
	}

	public int getmAverageScaleNumber() {
		return mAverageScaleNumber;
	}

	public void setmAverageScaleNumber(int mAverageScaleNumber) {
		this.mAverageScaleNumber = mAverageScaleNumber;
		invalidate();
	}

	public int getmScaleLineWidth() {
		return mScaleLineWidth;
	}

	public void setmScaleLineWidth(int mScaleLineWidth) {
		this.mScaleLineWidth = mScaleLineWidth;
		invalidate();
	}

	public int getmScalerLineHeight() {
		return mScalerLineHeight;
	}

	public void setmScalerLineHeight(int mScalerLineHeight) {
		this.mScalerLineHeight = mScalerLineHeight;
		invalidate();
	}

	public boolean isAverageScale() {
		return isAverageScale;
	}

	public void setAverageScale(boolean isAverageScale) {
		this.isAverageScale = isAverageScale;
		invalidate();
	}

	// private int getmWidth() {
	// return mWidth;
	// }
	//
	// private void setmWidth(int mWidth) {
	// this.mWidth = mWidth;
	// }

	public int getmHeight() {
		return mHeight;
	}

	public void setmHeight(int mHeight) {
		this.mHeight = mHeight;
	}

	public int getmProgressHeight() {
		return mProgressHeight;
	}

	public void setmProgressHeight(int mProgressHeight) {
		this.mProgressHeight = mProgressHeight;
		invalidate();
	}

	public int getmRadius() {
		return mRadius;
	}

	public void setmRadius(int mRadius) {
		this.mRadius = mRadius;
		invalidate();
	}

	public float getmBgProgressWidth() {
		return mBgProgressWidth;
	}

	public void setmBgProgressWidth(float mBgProgressWidth) {
		this.mBgProgressWidth = mBgProgressWidth;
		invalidate();
	}

	public float getmCenterProgressWidth() {
		return mCenterProgressWidth;
	}

	public void setmCenterProgressWidth(float mCenterProgressWidth) {
		this.mCenterProgressWidth = mCenterProgressWidth;
		invalidate();
	}

	public float getmAboveProgressWidth() {
		return mAboveProgressWidth;
	}

	public void setmAboveProgressWidth(float mAboveProgressWidth) {
		this.mAboveProgressWidth = mAboveProgressWidth;
		invalidate();
	}

	// ------------------------------------------------------------------Paint------------------
	public Paint getmDragClickPaint() {
		return mDragClickPaint;
	}

	public void setmDragClickPaint(Paint mDragClickPaint) {
		initPain(mDragClickPaint);
		this.mDragClickPaint = mDragClickPaint;
		invalidate();
	}

	public Paint getmScalePaint() {
		return mScalePaint;
	}

	public void setmScalePaint(Paint mScalePaint) {
		initPain(mScalePaint);
		this.mScalePaint = mScalePaint;
		invalidate();
	}

	public Paint getmBackgroundPaint() {
		return mBackgroundPaint;
	}

	public void setmBackgroundPaint(Paint mBackgroundPaint) {
		initPain(mBackgroundPaint);
		this.mBackgroundPaint = mBackgroundPaint;
		invalidate();
	}

	public Paint getmCenterPaint() {
		return mCenterPaint;
	}

	public void setmCenterPaint(Paint mCenterPaint) {
		initPain(mCenterPaint);
		this.mCenterPaint = mCenterPaint;
		invalidate();
	}

	public Paint getmAbovePaint() {
		return mAbovePaint;
	}

	public void setmAbovePaint(Paint mAbovePaint) {
		initPain(mAbovePaint);
		this.mAbovePaint = mAbovePaint;
		invalidate();
	}

	// ------------------------------------------------------------------Paint------------------

	public boolean isRoundRect() {
		return isRoundRect;
	}

	public void setRoundRect(boolean isRoundRect) {
		this.isRoundRect = isRoundRect;
		invalidate();
	}

	public float getmMaxValue() {
		return mMaxValue;
	}

	public void setmMaxValue(float mMaxValue) {
		this.mMaxValue = mMaxValue;
		invalidate();
	}

	public CanDragProgressView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init();
	}

	public CanDragProgressView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init();
	}

	public CanDragProgressView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		init();
	}

	/**
	 * 初始化
	 */
	private void init() {
		mBackgroundPaint = new Paint();
		mBackgroundPaint.setColor(Color.GRAY);
		mScalePaint = new Paint();
		mScalePaint.setColor(Color.GRAY);
		mScalePaint.setTextSize(16);
		mCenterPaint = new Paint();
		mCenterPaint.setColor(Color.BLUE);
		mAbovePaint = new Paint();
		mAbovePaint.setColor(Color.RED);
		mAbovePaint.setTextSize(45);
		mDragClickPaint = new Paint();
		mDragClickPaint.setColor(Color.BLACK);
		this.setOnTouchListener(this);
		initPain(mDragClickPaint);
		initPain(mBackgroundPaint);
		initPain(mScalePaint);
		initPain(mCenterPaint);
		initPain(mAbovePaint);
	}

	/**
	 * 初始化画笔
	 *
	 * @param paint
	 */
	private void initPain(Paint paint) {
		paint.setStyle(Paint.Style.FILL_AND_STROKE);
		paint.setAntiAlias(true);// 抗锯齿效果
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		setMeasuredDimension(widthMeasureSpec, 150);
	}
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		// TODO Auto-generated method stub
		mWidth = w;
		mHeight = h;
		mBgProgressWidth = mWidth;
		mCenterProgressWidth = 2 * mBgProgressWidth / 3;
		if (isDrawScaleUp) {
			mStartY = mScaleHeight + getFontHeight(mScalePaint) + 5;
			mProgressHeight = (int) (getFontHeight(mScalePaint) + mScaleHeight + mProgressRealHeight + 5 + mStartY);
		} else {
			mStartY = 60;
			mProgressHeight = (int) (mProgressRealHeight + mStartY);
		}
		mDragClickPaintRadius = (float) (mProgressRealHeight / 2 + 15);
		mRadius = (int) (mProgressRealHeight / 2 + 5);
		mDrawScaleWidth = (long) (mWidth - 2 * mDragClickPaintRadius);
		mScaleHeight = 10;
		mAboveProgressWidth = (mDrawScaleWidth*(mFirstValue/mMaxValue) + mDragClickPaintRadius);
		mCenterProgressWidth = (mDrawScaleWidth*(mSecondValue/mMaxValue) + mDragClickPaintRadius);
		super.onSizeChanged(w, h, oldw, oldh);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		// 绘制三个矩形
		drawRect(canvas, mBackgroundPaint, 0, mStartY, mBgProgressWidth, mProgressHeight);
//		Log.i("progress", mBgProgressWidth+"**"+mProgressHeight+"**"+mStartY+"**"+getFontHeight(mScalePaint));
		drawRect(canvas, mCenterPaint, 0, mStartY, mCenterProgressWidth, mProgressHeight);
		drawRect(canvas, mAbovePaint, 0, mStartY, mAboveProgressWidth, mProgressHeight);
		// 绘制刻度
		drawScales(canvas);
		// 绘制拖动点
		drawDragClick(canvas);
		// 绘制滚动数字
		drawChangeValue(canvas);

		super.onDraw(canvas);
	}
	/**
	 * 绘制滚动数字
	 * @param canvas
	 */
	private void drawChangeValue(Canvas canvas) {
		if (mAbovePaint.measureText(String.format("%1.2f", mFirstValue)) + mDrawScaleWidth*mFirstValue/mMaxValue > mWidth) {
			canvas.drawText(String.format("%1.2f", mFirstValue), mWidth - mAbovePaint.measureText(String.format("%1.2f", mFirstValue)), 3*getFontHeight(mAbovePaint)/4, mAbovePaint);
		}else {
			canvas.drawText(String.format("%1.2f", mFirstValue), mDrawScaleWidth*mFirstValue/mMaxValue, 3*getFontHeight(mAbovePaint)/4, mAbovePaint);
		}
	}

	/**
	 * 绘制拖动点
	 * @param canvas
	 */
	private void drawDragClick(Canvas canvas) {
		mDragClickPaint.setColor(Color.BLACK);
		RectF oval = new RectF(mAboveProgressWidth - mDragClickPaintRadius, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius, mAboveProgressWidth + mDragClickPaintRadius, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius);
		canvas.drawOval(oval, mDragClickPaint);
		mDragClickPaint.setColor(Color.WHITE);
		RectF oval2 = new RectF(mAboveProgressWidth - mDragClickPaintRadius + 1, mStartY + mProgressRealHeight/2 - mDragClickPaintRadius + 1, mAboveProgressWidth + mDragClickPaintRadius - 1, mStartY + mProgressRealHeight/2 + mDragClickPaintRadius - 1);
		canvas.drawOval(oval2, mDragClickPaint);
	}

	/**
	 * 绘制刻度
	 *
	 * @param canvas
	 */
	private void drawScales(Canvas canvas) {
		if (isDrawScale) {// 是否绘制刻度
			if (isAverageScale) {// 均分的刻度
				long unitLenght = mDrawScaleWidth / mAverageScaleNumber;// 单位长度
				if (isDrawScaleUp) {
					for (int i = 0; i < mAverageScaleNumber + 1; i++) {
						float startX = mDragClickPaintRadius + i * unitLenght;
						canvas.drawLine(startX, getFontHeight(mScalePaint), startX, mScaleHeight +getFontHeight(mScalePaint), mScalePaint);
						canvas.drawText(mMaxValue/mAverageScaleNumber*i+"", startX - mScalePaint.measureText(startX + "") / 2, getFontHeight(mScalePaint), mScalePaint);
					}
				} else {
					for (int i = 0; i < mAverageScaleNumber + 1; i++) {
						if (isDrawCenterScale) {
							float startX = mDragClickPaintRadius + i * unitLenght;
							float endY = mProgressHeight + 5 + mScaleHeight;
							canvas.drawLine(startX, mProgressHeight + 5, startX, endY, mScalePaint);
							canvas.drawText(mMaxValue/mAverageScaleNumber*i+"", startX - mScalePaint.measureText(startX + "") / 3, endY + getFontHeight(mScalePaint), mScalePaint);
						}else {
							if (i == 0 || i == mAverageScaleNumber) {
								float startX = mDragClickPaintRadius + i * unitLenght;
								float endY = mProgressHeight + 5 + mScaleHeight;
								canvas.drawLine(startX, mProgressHeight + 5, startX, endY, mScalePaint);
								canvas.drawText(mMaxValue/mAverageScaleNumber*i+"", startX - mScalePaint.measureText(startX + "") / 3, endY + getFontHeight(mScalePaint), mScalePaint);
							}
						}
					}
				}
			} else {
				if (isDrawScaleUp) {
					for (int i = 0; i < mScaleList.size(); i++) {
						double number = mScaleList.get(i);
						double unit = mDrawScaleWidth*(number/mMaxValue);
						float startX = (float) (mDragClickPaintRadius + unit);
						if (unit != 0) {
							canvas.drawLine(mDragClickPaintRadius, getFontHeight(mScalePaint), mDragClickPaintRadius, mScaleHeight +getFontHeight(mScalePaint), mScalePaint);
							canvas.drawText("0", mDragClickPaintRadius - mScalePaint.measureText("0") / 2, getFontHeight(mScalePaint), mScalePaint);
						}
						canvas.drawLine(startX, getFontHeight(mScalePaint), startX, mScaleHeight +getFontHeight(mScalePaint), mScalePaint);
						canvas.drawText(mScaleList.get(i)+"", startX - mScalePaint.measureText(""+mScaleList.get(i))/2, getFontHeight(mScalePaint), mScalePaint);
					}
				} else {
					for (int i = 0; i < mScaleList.size(); i++) {
						double number = mScaleList.get(i);
						double unit = mDrawScaleWidth*(number/mMaxValue);
						float startX = (float) (mDragClickPaintRadius + unit);
						float endY = mProgressHeight + 5 + mScaleHeight;
						if (unit != 0) {
							canvas.drawLine(mDragClickPaintRadius, mProgressHeight + 5, mDragClickPaintRadius, endY, mScalePaint);
							canvas.drawText("0", mDragClickPaintRadius - mScalePaint.measureText("0") / 2, endY + getFontHeight(mScalePaint), mScalePaint);
						}
						canvas.drawLine(startX, mProgressHeight + 5, startX, endY, mScalePaint);
						canvas.drawText(mScaleList.get(i)+"", startX - mScalePaint.measureText(""+mScaleList.get(i))/2, endY + getFontHeight(mScalePaint), mScalePaint);
					}
				}
			}
		}

	}

	/**
	 * 绘制矩形
	 *
	 * @param canvas
	 * @param paint
	 * @param left
	 *            左
	 * @param top
	 *            上
	 * @param right
	 *            右
	 * @param bottom
	 *            下
	 */
	private void drawRect(Canvas canvas, Paint paint, float left, float top, float right, float bottom) {
		RectF rectF = new RectF(left, top, right, bottom);
		if (isRoundRect) {
			canvas.drawRoundRect(rectF, mRadius, mRadius, paint);
		} else {
			canvas.drawRect(rectF, paint);
		}
	}

	/**
	 * 获取绘制的字体高度
	 *
	 * @param paint
	 * @return
	 */
	private int getFontHeight(Paint paint) {
		FontMetrics fm = paint.getFontMetrics();
		return (int) Math.ceil(fm.descent - fm.ascent);
	}
	private boolean isActionUp;
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		int code = event.getAction();
//		Log.i("progress", "onTouch"+mAboveProgressWidth);
		switch (code) {
		case MotionEvent.ACTION_DOWN:
			isActionUp = false;
			setOnTouchInit(event);
			break;
		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			isActionUp = true;
			setOnTouchInit(event);
			break;
		case MotionEvent.ACTION_MOVE:
			isActionUp = false;
			setOnTouchInit(event);
			break;
		}

		return true;
	}
	/**
	 * 触摸时设置边界
	 */
	private void setOnTouchInit(MotionEvent event){
		if (isTransfer) {
			if (event.getX() < mDragClickPaintRadius) {
				mAboveProgressWidth = mDragClickPaintRadius;
			}else if (event.getX() > mCenterProgressWidth) {
				mAboveProgressWidth = mCenterProgressWidth;
//				Log.i("progress", "onTouch"+mAboveProgressWidth + "***" + mCenterProgressWidth);
			}else {
				mAboveProgressWidth = event.getX();
			}
		}else {
			if (event.getX() < mDragClickPaintRadius) {
				mAboveProgressWidth = mDragClickPaintRadius;
			}else if (event.getX() > mWidth - mDragClickPaintRadius) {
				mAboveProgressWidth = mWidth - mDragClickPaintRadius;
			}else {
				mAboveProgressWidth = event.getX();
			}
		}
		mFirstValue = mMaxValue *( mAboveProgressWidth - mDragClickPaintRadius) / mDrawScaleWidth;
		if (mDragListener != null && isActionUp) {
			mDragListener.onDrag(this, getmFirstValue());
		}
		invalidate();
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
	}

}

That‘s all。

时间: 2024-10-10 23:22:43

Android 自定义进度条,的相关文章

Android自定义进度条样式

最近在做一个widget,上面需要一个progressbar,产品经理和设计师给出来的东西是要实现一个圆角的progress和自定义的颜色,研究一小下,分享出来给大家哦. 测试于:Android4.0+ 操作步骤: 1.创建你的layout文件引用progressbar如下,标红处引用你自定的样式: <ProgressBar android:id="@+id/progressDownload" style="?android:attr/progressBarStyleH

Android自定义进度条-带文本(文字进度)的水平进度条(ProgressBar)

/** * 带文本提示的进度条 */ public class TextProgressBar extends ProgressBar { private String text; private Paint mPaint; public TextProgressBar(Context context) { super(context); initText(); } public TextProgressBar(Context context, AttributeSet attrs, int d

android 自定义进度条颜色

先看图 基于产品经理各种自定义需求,经过查阅了解,下面是自己对Android自定义进度条的学习过程!   这个没法了只能看源码了,还好下载了源码, sources\base\core\res\res\  下应有尽有,修改进度条颜色只能找progress ,因为是改变样式,首先找styles.xml 找到xml后,进去找到 [html] view plaincopyprint? <span style="font-size: 18px;">    <style name

最简单的android自定义进度条样式

一.自定义圆形进度条样式 1.在安卓项目drawable目录下新建一个xml文件如下:<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:pivotX="50%" android:pivotY="50%" andro

自定义进度条(圆形、横向进度条)

自定义进度条实现大体流程 1.自定义属性声明(attrs文件) 2.自定义属性获取 3.测量(onMeasure) 4.绘制(onDraw) 代码: attrs文件: <!-- 自定义声明 --> <attr name="progress_unreach_color" format="color"></attr> <attr name="progress_unreach_height" format=&q

android113 自定义进度条

MainActivity: package com.itheima.monitor; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.ProgressBar; public class MainActivity extends Activity { private MyProgressBa

[Android]组件-进度条1

多式样ProgressBar 普通圆形ProgressBar 该类型进度条也就是一个表示运转的过程,例如发送短信,连接网络等等,表示一个过程正在执行中. 一般只要在XML布局中定义就可以了. <progressBar android:id="@+id/widget43" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layou

自定义进度条\文字描边样式\文字上下滚动TextSwithcher的应用

一.自定义进度条 1.<ProgressBar         android:id="@+id/patch_progress"         style="@style/gxProgressStyle"         android:layout_width="match_parent"         android:layout_height="12dp"         android:layout_alig

Android中进度条类型的控件定义和妙用技巧

Android中进度条控件有3个(不算ProgressDialog),分别是ProgressBar,SeekBar和RatingBar,对于自定义样式来说又得按照需求分为2中情况,第一种是刻度型,第二种是循环类型. 第一种是"刻度型",也就是他有起点和终点,起点值小于终点值 这种样式的修改,要修改三个属性即可 分别是:背景(主要是进度的轨道样式),第一级别滚动条progressDrawable,第二级别progressDrawable 遗憾的是Android提供的api很难设置,不过可