自定义seekbar实现验证功能
2019-03-22 本文已影响0人
guoheng1996
使用系统自带的seek bar,有一个问题,点击滑动条的时候,滑块会过去。。。
这里有个第三方库,效果可以看下:
https://github.com/MAXDeliveryNG/slideview
这个库做的还挺漂亮的,但是他有一个硬伤,在刚开始点击滑块的时候,滑块会右移。。
device-2019-03-22-104420.2019-03-22 10_48_42.gif尝试过给滑块设置一个margin,让滑块的右边和滑动条的右边挨着,这样可以一定程度上解决上面的问题,但是这样做的话,滑块就不跟手了,滑块会先到达后面,这时候只能手动计算滑动的距离,来修正这个问题。。。
有点麻烦,就放弃了。
然后就自己画一个view,本来我是用如下这种布局方式,然后设置监听touch事件,但是感觉有点low,于是就自己画了。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="270dp"
android:layout_height="45dp"
android:layout_marginStart="7dp"
android:layout_marginEnd="7dp"
android:layout_marginTop="12dp"
android:background="@drawable/layer_seekbar_progress"
android:clickable="true"
/>
<TextView
android:layout_width="270dp"
android:layout_height="45dp"
android:layout_marginStart="7dp"
android:layout_marginEnd="7dp"
android:layout_marginTop="12dp"
android:gravity="center"
android:textStyle="bold"
android:text="dsjfgdhjsfjksdhfl"
android:textColor="#ffffff"/>
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:background="@mipmap/btn_slide_to_pay"
android:clickable="false"/>
</FrameLayout>
屏幕快照 2019-03-22 11.19.16.png
具体的做法就是给滑动条设置touch时间的监听,然后动态的更改滑块的位置和背景色。
最后效果还不错。刚开始点击滑块,滑块也不会向右移动。
接下来,来看自定义的view。
device-2019-03-22-112259.2019-03-22 11_26_03.gif具体代码如下:
public class EPSlideView extends View {
private Paint paint;
private Bitmap slideBitmap;
private int margin;
private int slideBgWidth;
private int slideBgHeight;
private int slideBgRadius;
private int grey;
private int green;
private int white;
private int slideLeft;
private boolean slideIsMoving;
private int lastX;
private OnStopTrackingTouchListener onStopTrackingTouch;
private boolean isStartAnimator;
private int textSize;
private Rect textRect;
private int cleanColor;
public EPSlideView(Context context) {
super(context);
}
public EPSlideView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
margin = getResources().getDimensionPixelOffset(R.dimen.slide_margin);
slideBgWidth = getResources().getDimensionPixelOffset(R.dimen.slide_bg_width);
slideBgHeight = getResources().getDimensionPixelOffset(R.dimen.slide_bg_height);
slideBgRadius = getResources().getDimensionPixelOffset(R.dimen.slide_bg_radius);
textSize = getResources().getDimensionPixelOffset(R.dimen.common_text_size_16sp);
grey = ContextCompat.getColor(getContext(), R.color.grey_A8A8A9);
green = ContextCompat.getColor(getContext(), R.color.green_6bcd00);
white = ContextCompat.getColor(getContext(), R.color.white_color);
cleanColor = ContextCompat.getColor(getContext(), R.color.clear_color);
slideLeft = 0;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
slideBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.btn_slide_to_pay);
textRect = new Rect(slideBitmap.getWidth(), margin, slideBgWidth, slideBgHeight + margin);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
slideBitmap.recycle();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getRawX();
if (isStartAnimator) {
return false;
}
// check finger is touch above slide
if (event.getX() > slideLeft && event.getX() < slideBitmap.getWidth() + slideLeft) {
slideIsMoving = true;
return true;
}
return false;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
slideLeft += dx;
if (slideLeft < 0) {
slideLeft = 0;
}
if (slideLeft > slideBgWidth + margin * 2 - slideBitmap.getWidth()) {
slideLeft = slideBgWidth + margin * 2 - slideBitmap.getWidth();
}
if (slideIsMoving) {
invalidate();
lastX = (int) event.getRawX();
}
break;
case MotionEvent.ACTION_UP:
if (slideIsMoving) {
if (onStopTrackingTouch != null) {
if (slideLeft + slideBitmap.getWidth() >= slideBgWidth + margin * 2) {
onStopTrackingTouch.success();
} else {
onStopTrackingTouch.fail();
if (slideLeft > 0) {
backZero();
}
}
}
slideIsMoving = false;
}
break;
default:
break;
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
// paint grey bg
paint.setColor(grey);
canvas.drawRoundRect(slideLeft + slideBitmap.getWidth() - margin * 2, margin, slideBgWidth + margin,
slideBgHeight + margin, slideBgRadius, slideBgRadius, paint);
//paint green bg
paint.setColor(green);
canvas.drawRoundRect(margin, margin, slideLeft + margin * 2,
slideBgHeight + margin, slideBgRadius, slideBgRadius, paint);
//paint text
paint.setTextSize(textSize);
paint.setColor(cleanColor);
canvas.drawRect(textRect, paint);
paint.setColor(white);
paint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
int baseline = (textRect.bottom + textRect.top - fontMetrics.bottom - fontMetrics.top) / 2;
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(getResources().getString(R.string.confirm_amount_seekbar_text),
textRect.centerX(), baseline, paint);
//paint slide
canvas.drawBitmap(slideBitmap, slideLeft, 0, paint);
super.onDraw(canvas);
}
public void backZero() {
ObjectAnimator slideAnimator = ObjectAnimator.ofInt(this,
"slideLeft", this.slideLeft, 0);
slideAnimator
.setDuration(300).start();
slideAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
isStartAnimator = true;
}
@Override
public void onAnimationEnd(Animator animation) {
isStartAnimator = false;
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
@Keep
public void setSlideLeft(int slideLeft) {
this.slideLeft = slideLeft;
invalidate();
}
public void setOnStopTrackingTouch(OnStopTrackingTouchListener onStopTrackingTouch) {
this.onStopTrackingTouch = onStopTrackingTouch;
}
public interface OnStopTrackingTouchListener {
void success();
void fail();
}