android原生滑块验证

article/2025/11/9 8:12:02

记录一个滑块验证,在文章底部会放上DEMO

简单效果图

1、滑动验证前

 2、滑动验证后

 

用到两个类:

一、自定义类代码

public class ImageAuthenticationView extends android.support.v7.widget.AppCompatImageView {/*** 定义画笔*/private Paint mPaint;/*** 验证的图像*/private Bitmap mBitmap;/*** 验证滑块的高*/private int mUintHeight;/*** 验证滑块的宽*/private int mUintWidth;/*** 验证滑块宽占用整体图片大小的比例,默认1/12*/private int mUnitWidthScale;/*** 验证滑块高度占用整体图片大小的比例,默认1/10*/private int mUnitHeightScale;/*** 随机生成滑块的X坐标*/private int mUnitRandomX;/*** 随机生成滑块的Y坐标*/private int mUnitRandomY;/**** 滑块移动的距离*/private float mUnitMoveDistance = 0;/**** 滑块图像*/private Bitmap mUnitBp;/*** 验证位置图像*/private Bitmap mShowBp;/*** 背景阴影图像*/private Bitmap mShadeBp;/*** 是否需要旋转**/private boolean needRotate;/*** 旋转的角度*/private int rotate;/*** 判断是否完成的偏差量,默认为10*/public int DEFAULT_DEVIATE;/*** 判断是否重新绘制图像*/private boolean isReSet = true;/*** 拼图成功的回调**/public interface onPuzzleListener {public void onSuccess();public void onFail();}/*** 回调*/private onPuzzleListener mlistener;/*** 设置回调** @param listener*/public void setPuzzleListener(onPuzzleListener listener) {this.mlistener = listener;}public ImageAuthenticationView(Context context) {this(context, null);}public ImageAuthenticationView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ImageAuthenticationView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ImageAuthenticationView);mUintWidth = ta.getDimensionPixelOffset(R.styleable.ImageAuthenticationView_unitHeight, 0);mUintHeight = ta.getDimensionPixelOffset(R.styleable.ImageAuthenticationView_unitHeight, 0);mUnitHeightScale = ta.getInteger(R.styleable.ImageAuthenticationView_unitHeightScale, 10);mUnitWidthScale = ta.getInteger(R.styleable.ImageAuthenticationView_unitWidthScale, 12);Drawable showBp = ta.getDrawable(R.styleable.ImageAuthenticationView_unitShowSrc);mShowBp = drawableToBitamp(showBp);Drawable shadeBp = ta.getDrawable(R.styleable.ImageAuthenticationView_unitShadeSrc);mShadeBp = drawableToBitamp(shadeBp);needRotate = ta.getBoolean(R.styleable.ImageAuthenticationView_needRotate, true);DEFAULT_DEVIATE = ta.getInteger(R.styleable.ImageAuthenticationView_deviate, 10);ta.recycle();//初始化mPaint = new Paint();//抗锯齿mPaint.setAntiAlias(true);//是否需要旋转if (needRotate) {rotate = (int) (Math.random() * 3) * 90;} else {rotate = 0;}}/*** 随机生成生成滑块的XY坐标*/private void initUnitXY() {mUnitRandomX = (int) (Math.random() * (mBitmap.getWidth() - mUintWidth));mUnitRandomY = (int) (Math.random() * (mBitmap.getHeight() - mUintHeight));// 防止生成的位置距离太近if (mUnitRandomX <= mBitmap.getWidth() / 2) {mUnitRandomX = mUnitRandomX + mBitmap.getWidth() / 4;}// 防止生成的X坐标截图时导致异常if (mUnitRandomX + mUintWidth > getWidth()) {initUnitXY();return;}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (isReSet) {mBitmap = getBaseBitmap();if (0 == mUintWidth) {mUintWidth = mBitmap.getWidth() / mUnitWidthScale;}if (0 == mUintHeight) {mUintHeight = mBitmap.getHeight() / mUnitHeightScale;}initUnitXY();mUnitBp = Bitmap.createBitmap(mBitmap, mUnitRandomX, mUnitRandomY, mUintWidth, mUintHeight);}isReSet = false;canvas.drawBitmap(drawTargetBitmap(), mUnitRandomX, mUnitRandomY, mPaint);canvas.drawBitmap(drawResultBitmap(mUnitBp), mUnitMoveDistance, mUnitRandomY, mPaint);}/*** 重置*/public void reSet() {isReSet = true;mUnitMoveDistance = 0;if (needRotate) {rotate = (int) (Math.random() * 3) * 90;} else {rotate = 0;}invalidate();}/*** 获取每次滑动的平均偏移值** @return*/public float getAverageDistance(int max) {return (float) (mBitmap.getWidth() - mUintWidth) / max;}/*** 滑块移动距离** @param distance*/public void setUnitMoveDistance(float distance) {mUnitMoveDistance = distance;// 防止滑块滑出图片if (mUnitMoveDistance > mBitmap.getWidth() - mUintWidth) {mUnitMoveDistance = mBitmap.getWidth() - mUintWidth;}invalidate();}/*** 验证是否拼接成功*/public void testPuzzle() {if (Math.abs(mUnitMoveDistance - mUnitRandomX) <= DEFAULT_DEVIATE) {if (null != mlistener) {mlistener.onSuccess();}} else {if (null != mlistener) {mlistener.onFail();}}}/*** 创建目标图片(阴影部分)** @return*/private Bitmap drawTargetBitmap() {// 绘制图片Bitmap showB;if (null != mShowBp) {showB = handleBitmap(mShowBp, mUintWidth, mUintHeight);} else {showB = handleBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.puzzle_show), mUintWidth, mUintHeight);}// 如果需要旋转图片,进行旋转,旋转后为了保持和滑块大小一致,需要重新缩放比例if (needRotate) {showB = handleBitmap(rotateBitmap(rotate, showB), mUintWidth, mUintHeight);}return showB;}/*** 创建结滑块图片** @param bp*/private Bitmap drawResultBitmap(Bitmap bp) {// 绘制图片Bitmap shadeB;if (null != mShadeBp) {shadeB = handleBitmap(mShadeBp, mUintWidth, mUintHeight);} else {shadeB = handleBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.puzzle_shade), mUintWidth, mUintHeight);}// 如果需要旋转图片,进行旋转,旋转后为了和画布大小保持一致,避免出现图像显示不全,需要重新缩放比例if (needRotate) {shadeB = handleBitmap(rotateBitmap(rotate, shadeB), mUintWidth, mUintHeight);}Bitmap resultBmp = Bitmap.createBitmap(mUintWidth, mUintHeight,Bitmap.Config.ARGB_8888);Paint paint = new Paint();paint.setAntiAlias(true);Canvas canvas = new Canvas(resultBmp);canvas.drawBitmap(shadeB, new Rect(0, 0, mUintWidth, mUintHeight),new Rect(0, 0, mUintWidth, mUintHeight), paint);// 选择交集去上层图片paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));canvas.drawBitmap(bp, new Rect(0, 0, mUintWidth, mUintHeight),new Rect(0, 0, mUintWidth, mUintHeight), paint);return resultBmp;}/*** 获取实际显示的图片** @return*/public Bitmap getBaseBitmap() {//获取背景图片BitmapBitmap b = drawableToBitamp(getDrawable());float scaleX = 1.0f;float scaleY = 1.0f;// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;scaleX = getWidth() * 1.0f / b.getWidth();scaleY = getHeight() * 1.0f / b.getHeight();//按比例缩放Matrix matrix = new Matrix();matrix.setScale(scaleX, scaleY);Bitmap bd = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(),matrix, true);return bd;}/*** drawable转bitmap** @param drawable* @return*/private Bitmap drawableToBitamp(Drawable drawable) {if (null == drawable) {return null;}if (drawable instanceof BitmapDrawable) {BitmapDrawable bd = (BitmapDrawable) drawable;return bd.getBitmap();//该方法用于BitmapDrawable转换成Bitmap}//获取drawable的宽高int w = drawable.getIntrinsicWidth();int h = drawable.getIntrinsicHeight();//创建Bitmap后无法进行修改Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);//创建对应的Bitmap画布Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, w, h);drawable.draw(canvas);return bitmap;}/*** 缩放图片** @param bp* @param x* @param y* @return*/public static Bitmap handleBitmap(Bitmap bp, float x, float y) {int w = bp.getWidth();int h = bp.getHeight();float sx = (float) x / w;float sy = (float) y / h;Matrix matrix = new Matrix();matrix.postScale(sx, sy);Bitmap resizeBmp = Bitmap.createBitmap(bp, 0, 0, w,h, matrix, true);return resizeBmp;}/*** 旋转图片** @param degree* @param bitmap* @return*/public Bitmap rotateBitmap(int degree, Bitmap bitmap) {Matrix matrix = new Matrix();matrix.postRotate(degree);Bitmap bm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), matrix, true);return bm;}
}

具体说明代码中已经有说明。

二、主类引用监听结果代码

public class MainActivity extends Activity {//滑块private SeekBar mSeekBar;//自定义的控件private ImageAuthenticationView mDY;private Button btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initListener();}private void initView() {mDY = findViewById(R.id.dy_v);mSeekBar = findViewById(R.id.sb_dy);btn = findViewById(R.id.btn);}private void initListener() {//滑块监听mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int i, boolean b) {//设置滑块移动距离mDY.setUnitMoveDistance(mDY.getAverageDistance(seekBar.getMax()) * i);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {//验证是否拼接成功mDY.testPuzzle();}});//控件监听mDY.setPuzzleListener(new ImageAuthenticationView.onPuzzleListener() {@Overridepublic void onSuccess() {//mSeekBar.setEnabled(false);//禁止滑动Toast.makeText(MainActivity.this, "验证成功", Toast.LENGTH_SHORT).show();}@Overridepublic void onFail() {Toast.makeText(MainActivity.this, "验证失败", Toast.LENGTH_SHORT).show();mSeekBar.setProgress(0);}});//还原btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//mSeekBar.setEnabled(true);mSeekBar.setProgress(0);mDY.reSet();}});}

三、XML文件代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:dy="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"android:paddingLeft="10dp"android:paddingTop="10dp"android:paddingRight="10dp"android:paddingBottom="10dp"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="50sp"android:textSize="40sp"android:text="模块滑动验证demo"/><com.sjl.keeplive.slideImg.ImageAuthenticationViewandroid:id="@+id/dy_v"android:layout_width="match_parent"android:layout_height="wrap_content"android:scaleType="centerCrop"android:layout_marginBottom="10dp"android:src="@mipmap/grls"dy:needRotate="true"dy:unitHeight="60dp"dy:unitShadeSrc="@mipmap/puzzle_shade"dy:unitShowSrc="@mipmap/puzzle_show"dy:unitWidth="80dp" /><SeekBarandroid:id="@+id/sb_dy"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/bg_seekbar"android:max="150" /><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="还原"/>
</LinearLayout>

滑动模块全部代码,具体效果可以下载demo

DEMO下载

                                                                                             -END


http://chatgpt.dhexx.cn/article/PXA65sOX.shtml

相关文章

小程序 拖动滑块验证(自定义组件 插件分享)

效果图&#xff1a; 文章目录&#xff1a; #1 创建组件 #2 组件编码 MoveVerify.wxss MoveVerify.wxml MoveVerify.js #3 页面引用 在页面的 json 文件中引用组件 在页面的 wxml 文件中使用组件 在页面的 js 文件中接收验证回调 #1 创建组件 在小程序项目根目录创建目…

jQuery拖动滑块验证样式

样式&#xff1a; 目录结构&#xff1a; HTML代码&#xff1a; <!DOCTYPE html> <html><head><title>jQuery仿淘宝网拖动滑块验证码代码</title><meta charset"utf-8"><link href"css/drag.css" rel"stylesh…

css3 滑动验证,Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)

vue验证滑块功能&#xff0c;在生活中很多地方都可以见到&#xff0c;那么使用起来非常方便&#xff0c;基于vue如何实现滑块验证呢&#xff1f;下面通过代码给大家讲解。 效果图如下所示&#xff1a; 拖动前 拖动后 代码引用的css与js都是线上的 将代码全部复制到一个html中可…

JavaScript实现拖动滑块验证

Write By Monkeyfly 以下内容均为原创&#xff0c;如需转载请注明出处。 前提 之前在优化别人写的登录界面时&#xff0c;遇到了滑动解锁成功后发送短信验证码的场景&#xff0c;因为涉及到改动&#xff0c;所以必须要明白它是怎么实现的。由于本人JavaScript技艺不精&#…

JavaScript实现拖动滑块验证(方法已封装)

前提 之前写了一篇博文&#xff0c;题目是《JavaScript实现拖动滑块验证》&#xff0c;里面都是用最简单的方式实现的。后来&#xff0c;群里大神推荐了一款unlock.js插件&#xff0c;称作幻灯片解锁插件。在这里附上它的github地址&#xff1a;https://github.com/menthe/unl…

JavaScript封装拖动滑块验证

原生JS封装拖动验证滑块 最终效果分析最终如何使用&#xff1f;编写库的整体初始框架编写核心函数1(创建dom和css)编写核心函数2(绑定事件)添加工具方法(核心函数2中用到的) 最终完整可运行代码使用 最终效果 分析 看到这个效果我们首先应该想到和拖动有关的api: onmousedown, …

vue拖动滑块验证组件

组件Slider.vue <template><div class"drag" ref"dragDiv"><div class"drag_bg"></div><div class"drag_text">{{ confirmWords }}</div><div ref"moveDiv" mousedown"moused…

js实现拖动滑块验证

介绍一个比较6的网站&#xff1a;Element.setPointerCapture() - Web API 接口参考 | MDN 里面用到的setPointerCapture&#xff0c;getBoundingClientRect方法都是这个网站里面有的 &#xff08;看看效果图&#xff0c;动态图我不知道怎么搞&#xff0c;简单来说就是没拉到底…

php拖动滑块验证原理,原生js实现拖动滑块验证

原生js实现拖动滑块验证题 前言 验证的目的是为了减轻超高数据量的访问时,服务器的压力,减少同时请求量;前端基本都不能避免与验证打交道,这里记录一下我对于滑块验证的学习过程。 思路 作为前端,我们要将自己带入用户的角度,对用户的操作习惯进行考虑,我将拖动滑块验证…

Vue - 滑块拖动拼图验证(滑块验证安全检测)

前言 😃 提供您一个示例,您可以轻松移植到您项目中。 您一定见过很多系统都 “配备” 了滑块验证、拼图验证、找不同等, 本质上都是为了验证登录系统的是人还是机器(代码), 如下图所示效果:

Uipath实现简单的滑块拖动验证

本篇文章主要介绍使用【Click】Activities这一个活动来实现拖动滑块的验证&#xff0c;为拖动滑块验证提供了一种思路。但只能应用于滑块从头滑到尾&#xff0c;不支持拼图的滑块验证。 说白了&#xff0c;这篇文章更像是介绍【Click】这个Activities中&#xff0c;"clic…

数据库技术与应用 学习笔记1

1.软件的安装 SQL Server 2019 安装教程 大佬的安装教程链接: https://blog.csdn.net/CHQC388/article/details/104550963. 2.数据库技术与应用 2.1 什么是数据库技术 数据库技术所研究的问题就是如何科学地组织和存储数据&#xff0c;如何高效地获取和处理数据。 2.2 什么…

SQL Server数据库笔记整理(一)

数据库&#xff1a;持久化存储&#xff0c;优化读写&#xff0c;保证数据的有效性。 关系型数据库是基于E-R模型&#xff08;即实体-模型&#xff09;&#xff0c;使用SQL语言进行操作。数据库分类&#xff1a;文档型数据库、服务型数据库&#xff08;使用居多&#xff09; &am…

软件测试工程师学习笔记11 - 数据库篇

软件测试工程师学习笔记 -11 一、入门必读二、Linux三、数据库1.MySQL基础1&#xff09; sql语言的注释2&#xff09;mysql中常用数据类型3&#xff09;表、字段、记录4&#xff09;数据库中的常用命令4&#xff09;字段的约束5&#xff09;总结 一、入门必读 二、Linux 三、…

计算机三级 数据库技术 学习笔记

版权声明&#xff1a;本文为CSDN博主「RanLZ」的原创文章&#xff0c;转载请附上原文出处链接。 计算机三级 数据库技术 第一章 数据库应用系统开发方法 1.1 数据库应用系统生命周期 1.1.1 软件工程与软件开发方法 瀑布模型快速原型模型螺旋模型 1.1.2 DBAS生命周期模型 p …

数据库系统概论复习笔记

Ch1 绪论 1.1 基本概念 数据Data、数据库DB、数据库管理系统DBMS、数据库系统DBS 数据是数据库中存储的基本对象,是用来描述事物的符号。数据库是长期储存在计算机内的、有组织的、可共享的、大量数据的集合。数据库管理系统位于用户与操作系统之间的一层数据管理软件,用于…

数据库系统概论学习笔记(1)

数据库系统第一章 目录 数据库系统第一章1. 绪论1.1 数据库系统概述1.2 数据(Data)图解注意点例子 1.3 数据库(DataBase)注意点1.4 数据库管理系统(DateBase Management System DBMS)1.5 数据库系统(DateBase System,DBS)1.6 数据库管理的三个阶段 1. 绪论 1.1 数据库系统概述…

软件工程学习笔记

其他 【专栏必读】王道考研408操作系统万字笔记&#xff08;有了它不需要你再做笔记了&#xff09;&#xff1a;各章节内容概述导航和思维导图 【专栏必读】王道考研408数据结构万字笔记&#xff08;有了它不需要你再做笔记了&#xff09;&#xff1a;各章节内容概述导航和思维…

数据库原理第七章笔记

一、 数据库设计概述 数据库设计&#xff0c;广义的讲是数据库及其应用系统的设计&#xff0c;即整个数据库应用系统。狭义的讲是设计数据库本身&#xff0c;即设计数据库的各级模式并建立数据库&#xff0c;也是数据库应用系统设计的一部分。 数据库设计是指对于一个给定的应…

软件设计师学习笔记-数据库系统

目录 数据库系统 三级模式-两级映射 数据库设计过程 E-R模型 关系代数 规范化理论-函数依赖 规范化理论-价值与用途​ 规范化理论-键 规范化理论-求候选键 规范化理论-范式 规范化理论-模式分解 并发控制概念 并发控制存在的问题 并发控制的封锁协议 数据库完整…