好久没有机会画画控件,最近画了一个换汤不换药的控价,之前的开关是点击事件,这个响应拖拽。
说下我这个控件拖拽的原理,手指按下,判断当前手指位置是否为拖拽元素所处位置,如果是,将控制变量值改为true
在onMove 事件中重新计算拖拽元素位置并重绘
在其他事件中重新将控制变量值改为false,并且用回调返回当前控件选中值,先上一个效果图,然后源代码走起
public class MySeekBar extends View {
private int textColor;
private float textSize;
private int bgColor;
private int fgColor;
private float corner;
private int scope;
private float blockWidth;
private int blockColor;
private DragerListener dragerListener;
private boolean changeComplete = true;
private int nowPoint;
private float blockHeight;
private float scaleWidth;
private float space;
private float blockCorner;
float step=0;
private int getNowSelect(){
return scope-nowPoint;
}
public int getNowPoint() {
return nowPoint;
}
public void setNowPoint(int nowPoint) {
this.nowPoint = nowPoint;
}
public boolean isChangeComplete() {
return changeComplete;
}
public void setChangeComplete(boolean changeComplete) {
this.changeComplete = changeComplete;
}
public DragerListener getDragerListener() {
return dragerListener;
}
public void setDragerListener(DragerListener dragerListener) {
this.dragerListener = dragerListener;
}
// private int Width;
// private int Height;
public MySeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
public MySeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.MySeekBar);
textColor = a.getColor(R.styleable.MySeekBar_seek_textColor,
0XFFFFFFFF);
blockColor = a.getColor(R.styleable.MySeekBar_seek_blockColor, 0XFFFFFFFF);
textSize = a.getDimension(R.styleable.MySeekBar_seek_textSize, 36);
corner = a.getDimension(R.styleable.MySeekBar_seek_corner, 0);
bgColor = a.getColor(R.styleable.MySeekBar_seek_bgColor,
0XFFEAEAEA);
blockWidth=a.getDimension(R.styleable.MySeekBar_seek_blockWidth,30);
scope=a.getInteger(R.styleable.MySeekBar_seek_scope,30);
fgColor = a.getColor(R.styleable.MySeekBar_seek_fgColor, 0XFFFF0000);
blockHeight=a.getDimension(R.styleable.MySeekBar_seek_blockHeight,30);
space=a.getDimension(R.styleable.MySeekBar_seek_space,5);
scaleWidth=a.getDimension(R.styleable.MySeekBar_seek_scale_width,30);
blockCorner=a.getDimension(R.styleable.MySeekBar_seek_block_corner,10);
nowPoint=1;
a.recycle();
}
public MySeekBar(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
step=(getHeight() - corner * 2) / scope;
float lineStart = corner + step / 2;
Paint tPaint = new Paint();
tPaint.setAntiAlias(true);
tPaint.setTextSize(textSize);
tPaint.setColor(textColor);
Paint.FontMetricsInt fontMetrics = tPaint.getFontMetricsInt();
Paint bgPaint = new Paint();
bgPaint.setColor(bgColor);
Paint fgPaint = new Paint();
fgPaint.setColor(fgColor);
Paint blockPaint = new Paint();
blockPaint.setColor(blockColor);
blockPaint.setStyle(Paint.Style.FILL_AND_STROKE);
RectF bgRect = new RectF();
bgRect.top = 0;
bgRect.right = getWidth();
bgRect.left = 0;
bgRect.bottom = getHeight();
canvas.drawRoundRect(bgRect, corner, corner, bgPaint);
RectF fgRect = new RectF();
fgRect.top = corner;
fgRect.right = scaleWidth+space+blockWidth/2+3;
fgRect.left = scaleWidth+space+blockWidth/2-3;
fgRect.bottom = getHeight()-corner;
canvas.drawRoundRect(fgRect, 0, 0, fgPaint);
for (int i = 0; i < scope; i++) {
canvas.drawLine(0, lineStart + step * i, scaleWidth, lineStart + step * i,
fgPaint);
canvas.drawLine(0+scaleWidth+blockWidth+space*2, lineStart + step * i, scaleWidth*2+blockWidth+space*2, lineStart + step * i,
fgPaint);
float baseline = corner+step*i - fontMetrics.bottom - fontMetrics.top;//垂直居中
canvas.drawText((scope - i) + "", scaleWidth*2+space*2+blockWidth, baseline, tPaint);
}
RectF blockRect = new RectF();
blockRect.top = step*nowPoint+corner;
blockRect.right = scaleWidth+space+blockWidth;
blockRect.left = scaleWidth+space;
blockRect.bottom = step*nowPoint+corner+blockHeight;
canvas.drawRoundRect(blockRect, blockCorner, blockCorner, blockPaint);
}
boolean isDrag=false;
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
if(event.getY()> corner+step*nowPoint&&event.getY()<step*nowPoint+corner+blockHeight){
isDrag=true;
}
}else if(event.getAction()==MotionEvent.ACTION_MOVE){
if(isDrag) {
nowPoint = (int) ((event.getY() - corner) / step);
if (nowPoint < 0) {
nowPoint = 0;
}
if (nowPoint >= scope) {
nowPoint = scope-1;
}
invalidate();
}
} else{
isDrag=false;
dragerListener.change(getNowSelect());
}
return true;
}
public interface DragerListener {
void change(int select);
}
}
<包名(路径名).MySeekBar
android:visibility="gone"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:seek_bgColor="#adadad"
app:seek_fgColor="#f3000000"
app:seek_textSize="8dp"
app:seek_padding="2dp"
app:seek_blockColor="#ff0f0f0f"
app:seek_textColor="@color/black"
app:seek_block_corner="3dp"
app:seek_scope="30"
app:seek_blockWidth="30dp"
app:seek_corner="5dp"
app:seek_scale_width="10dp"
app:seek_blockHeight="10dp"
app:seek_space="3dp"
android:id="@+id/seekBar"
/>
binding.seekBar.setDragerListener {
selected->
Toast.makeText(context, "selected$selected", Toast.LENGTH_SHORT).show();
}