自定义滑块验证View
来源:互联网 发布:php中文手册下载 编辑:程序博客网 时间:2024/06/05 18:02
最近项目上要把原先发送验证码的地方的图片验证改成滑块验证,于是重新自定义了一个View,先来看一下实现的效果图:
中间那个可以拖动的滑块就是一个自定义View,下面贴上它的实现代码:
package 马赛克.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import 马赛克;import 马赛克.CommonUtil;/** * Created by sjb on 2016/6/30. * 拖动验证的小滑块 */public class BlockVerifyView extends View { /** * 滑块起点的X坐标 */ private float mBlockStartX; /** * 滑块终点的X坐标 */ private float mBlockEndX; /** * 上一个X坐标 */ private float mLastX; /** * 画笔 */ private Paint mPaint; private Paint mBgPaint; private boolean isSuccess; private OnVerifyListener listener; public interface OnVerifyListener { void success(); void fail(); } public void setOnVerifyListener(OnVerifyListener onVerifyListener) { this.listener = onVerifyListener; } public BlockVerifyView(Context context) { super(context); init(); } public BlockVerifyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public BlockVerifyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); mBgPaint = new Paint(); mBgPaint.setAntiAlias(true); mBgPaint.setColor(getResources().getColor(R.color.sa_light_g)); mBgPaint.setStyle(Paint.Style.STROKE); } private int getMeasure(int measure, int defaultSize) { int result = 300; int mode = MeasureSpec.getMode(measure); int size = MeasureSpec.getSize(measure); if (mode == MeasureSpec.EXACTLY) { result = size; } else if (mode == MeasureSpec.AT_MOST) { result = Math.min(CommonUtil.dip2px(getContext(), defaultSize), size); } return result; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(getMeasure(widthMeasureSpec, 300), getMeasure(heightMeasureSpec, 40)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mBlockStartX = getWidth() * 0.05f; mBlockEndX = mBlockStartX + getWidth() * 0.15f; } @Override protected void onDraw(Canvas canvas) { drawText(canvas); drawLeftArea(canvas); drawWhiteBlock(canvas); drawThreeRec(canvas); if (isSuccess) { drawSuccess(canvas); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (event.getX() > mBlockStartX && event.getX() < mBlockEndX) { mLastX = event.getX(); return true; } break; case MotionEvent.ACTION_MOVE: if (event.getY() > 0 && event.getY() < getHeight()) { if ((mBlockStartX + event.getX() - mLastX) > getWidth() * 0.05f && (mBlockStartX + event.getX() - mLastX + getWidth() * 0.15f) < getWidth()) { mBlockStartX += event.getX() - mLastX; mBlockEndX = mBlockStartX + getWidth() * 0.15f; mLastX = event.getX(); if (getWidth() - mBlockEndX < 10) { isSuccess = true; } else { isSuccess = false; } invalidate(); return true; } } break; case MotionEvent.ACTION_UP: if (listener != null) { if (getWidth() - mBlockEndX < 10) { listener.success(); } else { listener.fail(); } return true; } break; default: break; } return super.onTouchEvent(event); } /** * 绘制文字 * * @param canvas */ private void drawText(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.sa_light_g)); mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setTextSize(CommonUtil.dip2px(getContext(), 12)); Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt(); int baseline = (getHeight() + 0 - fontMetrics.bottom - fontMetrics.top) / 2; canvas.drawText("按住滑块拖至最右边", getWidth() * 0.5f, baseline, mPaint); } /** * 绘制左侧已滑过的区域 */ private void drawLeftArea(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.block_bg)); mPaint.setStyle(Paint.Style.FILL); canvas.drawRect(0, 0, mBlockStartX, getHeight(), mPaint); } /** * 绘制白色小滑块 */ private void drawWhiteBlock(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.white)); mPaint.setStyle(Paint.Style.FILL); canvas.drawRect(mBlockStartX, 0, mBlockEndX, getHeight(), mPaint); canvas.drawRect(mBlockStartX - 2, 0, mBlockEndX + 2, getHeight(), mBgPaint); } /** * 绘制滑块上的三条矩形区域 */ private void drawThreeRec(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.block_bg)); mPaint.setStyle(Paint.Style.FILL); float totalBlockX = mBlockEndX - mBlockStartX; canvas.drawRect(mBlockStartX + totalBlockX * 0.25f, 10, mBlockStartX + totalBlockX * 0.30f, getHeight() - 10, mPaint); canvas.drawRect(mBlockStartX + totalBlockX * 0.475f, 10, mBlockStartX + totalBlockX * 0.525f, getHeight() - 10, mPaint); canvas.drawRect(mBlockStartX + totalBlockX * 0.7f, 10, mBlockStartX + totalBlockX * 0.75f, getHeight() - 10, mPaint); } /** * 验证通过后绘制 * @param canvas */ private void drawSuccess(Canvas canvas) { mPaint.setColor(getResources().getColor(R.color.white)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(3); Path path = new Path(); path.moveTo(getWidth() * 0.5f - 20, getHeight() * 0.5f - 10); path.lineTo(getWidth() * 0.5f, getHeight() * 0.5f + 10); path.lineTo(getWidth() * 0.5f + 20, getHeight() * 0.5f - 30); canvas.drawPath(path, mPaint); }}
代码不难,控制好坐标就可以了。
其中定义了一个接口OnVerifyListener ,供使用者进行验证通过和失败时的处理,每次手指离开时进行回调。
但是这个View用在这个有键盘弹出的界面还是出现了一点小插曲,下面的这段代码:
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mBlockStartX = getWidth() * 0.05f; mBlockEndX = mBlockStartX + getWidth() * 0.15f; }
刚开始我是写在这里的:
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { mBlockStartX = getWidth() * 0.05f; mBlockEndX = mBlockStartX + getWidth() * 0.15f; }
用在这里发现每次键盘弹出或隐藏时,滑块都会回到初始位置,不能停留在上次的绘图状态,这下就尴尬了不是。
于是在这个View的各个方法中打印日志,发现每次键盘弹出或隐藏时,都回调了onLayout
方法,难怪位置又被初始化了……
好的,那就改变策略,在onSizeChanged
中初始化试试,结果只能是完美!
于是一个滑块验证就这样ko了~
欢迎吐槽、拍砖、卖萌……
0 0
- 自定义滑块验证View
- 自定义View-输入验证码
- Android 自定义View (验证码)
- 自定义view之一:自定义验证码控件
- 滑块拖动验证
- ListView自定义滑块
- 自定义View实现验证码效果
- Android自定义View--验证码控件
- Android自定义View(一)(验证码)
- Android自定义View实现验证码
- 自定义view(一)--随机验证码
- android 自定义View生成验证码
- android自定义view之刷新验证码
- android自定义验证码倒计时View
- Android自定义View实现随机验证码
- 自定义View(类似验证码)
- Android发送验证码倒计时自定义View
- 自定义View初学笔记之验证码
- JVM原理笔记
- Android源码编译之:KeyError: 'ui_strings.grd' make: *** [out/target/product/generic/obj/GYP/shared_interme
- Lintcode_89 k Sum
- 69. Sqrt(x)
- 第38课:Kafka源码解读Producer工作机制内幕
- 自定义滑块验证View
- 勾股定理一日一证连载40
- Python程序-生成回文
- android studio 出现拼写错误,将拼写错误的单词加入词库
- 5.1 Python序列
- 5.2 Python序列的操作
- 5.3 Python字符串深入探讨
- 5.4 Python字符串格式化
- 5.5 Python列表