• [Android实例] 拖动滑块进行图片拼合验证方式的实现


     

    该篇文章从eoeAndroid搬迁过来的,原文地址:[Android实例] 拖动滑块进行图片拼合验证方式的实现

    现在网站上有各种各样的验证码验证方式,比如计算大小,输入图片内容等,今天在一家网站上看到这样的一种效果,感觉眼前一亮,验证方式是给出一张缺失一点的图片,然后在旁边有缺失部分的滑块,需要将该滑块拖动到图片缺失的地方补全才能验证成功,看到这种方式,我就想如何在android上去实现这种滑动验证的效果。 
    我的思路是,自定义控件,重写onDraw方法

    1.根据原图和控件的大小裁剪出对应比例的背景图片,然后在控件中绘制出该背景图片

    // 根据原图进行裁剪出适合当前屏幕的背景图
            if (bgBitmap == null) {
                if (bitmap == null) {
                    return;
                }
                bgBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
                Canvas bgCanvas = new Canvas(bgBitmap);
                Rect bgRect;
                if (bitmap.getWidth() / getWidth() < bitmap.getHeight() / getHeight()) {
                    bgRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getWidth() * bitmap.getHeight() / getWidth());
                } else {
                    bgRect = new Rect(0, 0, bitmap.getWidth() * bitmap.getHeight() / getHeight(), bitmap.getHeight());
                }
                bgCanvas.drawBitmap(bitmap, bgRect, new Rect(0, 0, getWidth(), getHeight()), paint);
                bitmap.recycle();
                bitmap = null;
            }
            // 绘制背景图
            canvas.drawBitmap(bgBitmap, null, new Rect(0, 0, getWidth(), getHeight()), paint);

    2.计算背景图片缺失部分的左上角的位置,以及缺失部分图片所在初始位置的起点,绘制缺失部分的位置并裁剪缺失部分的图片

    // 计算验证的点和拖动起点
                    if (verifyPoint == null) {
                            int width = getWidth();
                            int height = getHeight();
                            int randomY = (int) (Math.random() * height);
                            int verifyX = width * 3 / 4 - 10;
                            int verifyY = randomY + height / 4 + 10 > height ? height * 3 / 4 - 10 : randomY;
                            verifyPoint = new Point(verifyX, verifyY);
                            startPoint = new Point(10, verifyY);
                    }
                    paint.setColor(Color.GRAY);
                    paint.setStyle(Paint.Style.FILL);
                    paint.setAntiAlias(true);
                    // 绘制验证的位置
                    Rect verifyRect = new Rect(verifyPoint.x, verifyPoint.y, verifyPoint.x + getWidth() / 4,
                                    verifyPoint.y + getHeight() / 4);
                    canvas.drawRect(verifyRect, paint);
                    // 裁剪拖动的图片
                    if (verifyBitmap == null) {
                            verifyBitmap = Bitmap.createBitmap(getWidth() / 4, getHeight() / 4, Config.ARGB_8888);
                            Canvas verifyCanvas = new Canvas(verifyBitmap);
                            verifyCanvas.drawBitmap(bgBitmap, verifyRect,
                                            new Rect(0, 0, verifyBitmap.getWidth(), verifyBitmap.getHeight()), paint);
                    }

    3.绘制裁剪的缺失部分图片

    // 拖动图片的绘制
                    if (isMoving) {// 拖动中
                            canvas.drawRect(new Rect(movePoint.x - 2, movePoint.y - 2, movePoint.x + getWidth() / 4 + 2,
                                            movePoint.y + getHeight() / 4 + 2), paint);
                            canvas.drawBitmap(verifyBitmap, null,
                                            new Rect(movePoint.x, movePoint.y, movePoint.x + getWidth() / 4, movePoint.y + getHeight() / 4),
                                            paint);
                    } else {
                            canvas.drawRect(new Rect(startPoint.x - 2, startPoint.y - 2, startPoint.x + getWidth() / 4 + 2,
                                            startPoint.y + getHeight() / 4 + 2), paint);
                            canvas.drawBitmap(verifyBitmap, null,
                                            new Rect(startPoint.x, startPoint.y, startPoint.x + getWidth() / 4, startPoint.y + getHeight() / 4),
                                            paint);
                    }

    4.重写onTouchEvent方法

    @Override
            public boolean onTouchEvent(MotionEvent event) {
                    // TODO Auto-generated method stub
                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                            if (event.getX() > startPoint.x && event.getX() < startPoint.x + getWidth() / 4
                                            && event.getY() > startPoint.y && event.getY() < startPoint.y + getHeight() / 4) {
                                    movePoint = new Point(startPoint);
                                    moveX = (int) event.getX();
                                    isMoving = true;
                                    invalidate();
                                    return true;
                            }
                            break;
                    case MotionEvent.ACTION_MOVE:
                            if (isMoving) {
                                    if (movePoint.x + getWidth() / 4 < getWidth() && movePoint.x > 0) {
                                            invalidate();
                                    }
                                    movePoint = new Point((int) (movePoint.x + event.getX() - moveX), movePoint.y);
                                    moveX = (int) event.getX();
                                    return true;
                            }
                            break;
                    case MotionEvent.ACTION_UP:
                            if (isMoving) {
                                    if (onVerifyListener != null) {
                                            if (Math.abs(movePoint.x - verifyPoint.x) < 10) {
                                                    onVerifyListener.success();
                                            } else {
                                                    onVerifyListener.fail();
                                            }
                                    }
                                    isMoving = false;
                                    movePoint = null;
                                    moveX = 0;
                                    invalidate();
                                    return true;
                            }
                            break;
                    default:
                            break;
                    }
                    return super.onTouchEvent(event);
            }

    这里写图片描述

    下载地址:项目代码

     
     
  • 相关阅读:
    初始v4l2(六)-------根据虚拟驱动vivi的使用彻底分析摄像头驱动
    初识v4l2(五)-------v4l2_ioctl浅析
    初识v4l2(四)-------v4l2_open、v4l2_read、v4l2_write浅析
    初识V4L2(三)-------分析vivi.c 虚拟视频驱动
    初识V4l2(二)-------浅析video_register_device
    初识V4L2(一)
    构建根文件系统之根文件系统(三)
    构建根文件系统之构建根文件系统(二)
    构建根文件系统之根文件系统
    vscode在软件内部查看html渲染效果的插件
  • 原文地址:https://www.cnblogs.com/xgjblog/p/7483413.html
Copyright © 2020-2023  润新知