Android滑动拼图验证码控件使用方法详解
更新时间:2021年8月27日 16:00 点击:1572
简介: 很多软件为了安全防止恶意攻击,会在登录/注册时进行人机验证,常见的人机验证方式有:谷歌点击复选框进行验证,输入验证码验证,短信验证码,语音验证,文字按顺序选择在图片上点击,滑动拼图验证等。
效果图:
代码实现:
1、滑块视图类:SlideImageView.java。实现随机选取拼图位置,对拼图位置进行验证等功能。
public class SlideImageView extends View { Bitmap bitmap; Bitmap drawBitmap; Bitmap verifyBitmap; boolean reset = true; // 拼图的位置 int x; int y; // 验证的地方 int left, top, right, bottom; // 移动x坐标 int moveX; // x坐标最大移动长度 int moveMax; // 正确的拼图x坐标 int trueX; public SlideImageView(Context context) { super(context); } public SlideImageView(Context context, AttributeSet attrs) { super(context, attrs); } public SlideImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (bitmap == null) return; if (reset) { /* * 背景图 */ int width = getWidth(); int height = getHeight(); drawBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); /* * 验证的地方 */ int length = Math.min(width, height); length /= 4;//1/4长度 // 随机选取拼图的位置 x = new Random().nextInt(width - length * 2) + length; y = new Random().nextInt(height - length * 2) + length; left = x; top = y; right = left + length; bottom = top + length; //验证的图片 verifyBitmap = Bitmap.createBitmap(drawBitmap, x, y, length, length); // 验证图片的最大移动距离 moveMax = width - length; // 正确的验证位置x trueX = x; reset = false; } Paint paint = new Paint(); // 画背景图 canvas.drawBitmap(drawBitmap, 0, 0, paint); paint.setColor(Color.parseColor("#66000000")); canvas.drawRect(left, top, right, bottom, paint);//画上阴影 paint.setColor(Color.parseColor("#ffffffff")); canvas.drawBitmap(verifyBitmap, moveX, y, paint);//画验证图片 } public void setImageBitmap(Bitmap bitmap) { this.bitmap = bitmap; } public void setMove(double precent) { if (precent < 0 || precent > 1) return; moveX = (int) (moveMax * precent); invalidate(); } public boolean isTrue(double range) { if (moveX > trueX * (1 - range) && moveX < trueX * (1 + range)) { return true; } else { return false; } } public void setReDraw() { reset = true; invalidate(); } }
2、视图布局文件:activity_main.xml。
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.slideimage.MainActivity"> <com.slideimage.SlideImageView android:id="@+id/slide_image_view" android:layout_width="240dp" android:layout_height="150dp" android:layout_marginTop="50dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <View android:id="@+id/flash_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="invisible" app:layout_constraintLeft_toLeftOf="@id/slide_image_view" app:layout_constraintRight_toRightOf="@id/slide_image_view" app:layout_constraintTop_toTopOf="@id/slide_image_view" app:layout_constraintBottom_toBottomOf="@id/slide_image_view" android:background="@mipmap/drag_flash"/> <SeekBar android:id="@+id/seekBar1" android:layout_width="240dp" android:layout_height="wrap_content" android:layout_marginTop="220dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <TextView android:id="@+id/show_result" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="280dp" android:textSize="20sp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="320dp" android:text="重新初始化" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> </android.support.constraint.ConstraintLayout>
3、在Activity中使用滑块验证:MainActivity.java。
public class MainActivity extends AppCompatActivity { private SeekBar seekBar; private Button button1; private SlideImageView slideImageView; private TextView resultText; private View flashView; private static final int flashTime = 800; private long timeStart = 0; private float timeUsed; @SuppressLint("ClickableViewAccessibility") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); seekBar = findViewById(R.id.seekBar1); button1 = findViewById(R.id.button1); slideImageView = findViewById(R.id.slide_image_view); flashView = findViewById(R.id.flash_view); resultText = findViewById(R.id.show_result); slideImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.slide_bg)); seekBar.setMax(10000); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { slideImageView.setMove(progress*0.0001); } @Override public void onStartTrackingTouch(SeekBar seekBar) { timeStart = System.currentTimeMillis(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); seekBar.setOnTouchListener(new View.OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_UP: timeUsed = (System.currentTimeMillis() - timeStart) / 1000.0f; boolean isTrue = slideImageView.isTrue(0.1);//允许有10%误差 if(isTrue) { flashShowAnime(); updateText("验证成功,耗时:" + timeUsed + "秒"); } else { updateText("验证失败"); } break; } return false; } }); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { reInit(); } }); } private void updateText(final String s) { runOnUiThread(new Runnable() { @Override public void run() { resultText.setText(s); } }); } private void reInit() { slideImageView.setReDraw(); seekBar.setProgress(0); resultText.setText(""); flashView.setVisibility(View.INVISIBLE); } // 成功高亮动画 private void flashShowAnime() { TranslateAnimation translateAnimation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 1f, Animation.RELATIVE_TO_SELF, -1f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f); translateAnimation.setDuration(flashTime); //translateAnimation.setInterpolator(new LinearInterpolator()); flashView.setVisibility(View.VISIBLE); flashView.setAnimation(translateAnimation); translateAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { flashView.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
相关文章
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- 最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 这篇文章主要为大家详细介绍了jQuery实现下拉菜单滑动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-09
jQuery Real Person验证码插件防止表单自动提交
本文介绍的jQuery插件有点特殊,防自动提交表单的验证工具,就是我们经常用到的验证码工具,先给大家看看效果。效果图如下: 使用说明 需要使用jQuery库文件和Real Person库文件 同时需要自定义验证码显示的CSS样式 使用实例...2015-11-08- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 这篇文章主要为大家详细介绍了JS实现随机生成验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-06
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
- 通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能效果图:先到官网(http://plugins.jquery.com/cookie/)下载cookie插件,放到相应文件夹,代码如下:复制代码 代码如下: <!DOCTYPE ht...2015-03-15
- 验证码类文件 CreateImg.class.php <?php class ValidationCode { private $width,$height,$codenum; public $checkcode; //产生的验证码 private $checkimage; //验证码图片 private $disturbColor = ''; /...2015-11-08
- 这篇文章主要为大家详细介绍了uniapp 实现可以左右滑动导航栏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-10-21