如题,看效果图:
该自定义组件的优势:
1、使用简单;
2、可随意改变圆点、直线的颜色和大小;
当然,也许你会吐槽,系统不是提供了 seekBar 吗,怎么不用 seekBar。
我想说,我写这个也是一时来了兴致,因为最近在研究自定义组件,根据自己项目里的需求,自己写出来的。虽然DEMO不是很高大上,但内心还是很欣喜的。所以,还希望嘴上留情。
还是那句话,你可以不爱,但请不要伤害。
直接晒代码
package com.junhui.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.ColorRes;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.junhui.R;
/**
* 可触摸进度视图
* <p>
* Created by 晖仔(Milo) on 2017/2/20.
* email:303767416@qq.com
*/
public class TouchProgressView extends View {
private static final String TAG = "TouchProgressView";
private Paint linePaint;
private Paint pointPaint;
private int pointRadius = 10;//圆点默认半径,单位px
private int pointColor = R.color.gray_dft;//圆点默认颜色
private int lineHeight = 2;//线默认高度,单位px
private int lineClor = R.color.gray_dft;//线默认颜色
private int progress = 0;
private final int PROGRESS_MIN = 0;
private final int PROGRESS_MAX = 100;
private OnProgressChangedListener progressChangedListener;
public interface OnProgressChangedListener {
void onProgressChanged(View view, int progress);
}
public TouchProgressView(Context context) {
super(context, null);
}
public TouchProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TouchProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 设置圆点半径
*
* @param radius
*/
public void setPointRadius(final int radius) {
if (radius <= 0) {
throw new IllegalArgumentException("radius 不可以小于等于0");
}
if (getWidth() == 0) {
post(new Runnable() {
@Override
public void run() {
if (radius * 2 > getWidth()) {
throw new IllegalArgumentException("radius*2 必须小于 view.getWidth() == " + getWidth());
}
pointRadius = radius;
}
});
} else {
if (radius * 2 > getWidth()) {
throw new IllegalArgumentException("radius*2 必须小于 view.getWidth() == " + getWidth());
}
this.pointRadius = radius;
}
}
/**
* 设置圆点颜色
*
* @param color
*/
public void setPointColor(@ColorRes int color) {
this.pointColor = color;
}
/**
* 设置直线高度
*
* @param height
*/
public void setLineHeight(int height) {
if (height <= 0) {
throw new IllegalArgumentException("height 不可以小于等于0");
}
this.lineHeight = height;
}
/**
* 设置直线颜色
*
* @param color
*/
public void setLineColor(@ColorRes int color) {
this.lineClor = color;
}
/**
* 设置百分比
*
* @param progress
*/
public void setProgress(int progress) {
if (progress < 0 || progress > 100) {
throw new IllegalArgumentException("progress 不可以小于0 或大于100");
}
this.progress = progress;
invalidate();
if (progressChangedListener != null) {
progressChangedListener.onProgressChanged(this, progress);
}
}
/**
* 设置进度变化监听器
*
* @param onProgressChangedListener
*/
public void setOnProgressChangedListener(OnProgressChangedListener onProgressChangedListener) {
this.progressChangedListener = onProgressChangedListener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getX() < pointRadius) {
setProgress(PROGRESS_MIN);
return true;
} else if (event.getX() > getWidth() - pointRadius) {
setProgress(PROGRESS_MAX);
return true;
} else {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setProgress(calculProgress(event.getX()));
return true;
case MotionEvent.ACTION_MOVE:
setProgress(calculProgress(event.getX()));
return true;
}
}
return super.onTouchEvent(event);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void draw(Canvas canvas) {
Log.d(TAG, "[draw] .. in .. ");
super.draw(canvas);
linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setStyle(Paint.Style.FILL);
linePaint.setStrokeWidth(lineHeight);
linePaint.setColor(getResources().getColor(lineClor));
//因为是以画布Canvas 为draw对象,所以RectF构造函数内的参数是以canvas为边界,而不是屏幕
canvas.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2, linePaint);
pointPaint = new Paint();
pointPaint.setAntiAlias(true);
pointPaint.setStyle(Paint.Style.FILL);
pointPaint.setColor(getResources().getColor(pointColor));
canvas.drawCircle(getCx(), getHeight() / 2, pointRadius, pointPaint);
}
/**
* 获取圆点的x轴坐标
*
* @return
*/
private float getCx() {
float cx = 0.0f;
cx = (getWidth() - pointRadius * 2);
if (cx < 0) {
throw new IllegalArgumentException("TouchProgressView 宽度不可以小于 2 倍 pointRadius");
}
return cx / 100 * progress + pointRadius;
}
/**
* 计算触摸点的百分比
*
* @param eventX
* @return
*/
private int calculProgress(float eventX) {
float proResult = (eventX - pointRadius) / (getWidth() - pointRadius * 2);
return (int) (proResult * 100);
}
}
以上就是完整代码,有不懂的可以留言提问,看到就会回答的。
DEMO下载地址:
Git: https://github.com/yanjunhui2014/TouchProgressView
CSDN:http://download.csdn.net/detail/yanjunhui2011/9758893
原创不易,转载记得附源自: http://write.blog.csdn.net/postedit/56016414