iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android自定View实现滑动验证效果的代码
  • 822
分享到

Android自定View实现滑动验证效果的代码

2024-04-02 19:04:59 822人浏览 薄情痞子
摘要

效果图 自定义属性代码 <?xml version="1.0" encoding="utf-8"?> <resources> &

效果图

效果图

自定义属性代码


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCheckView">
        <attr name="m_blockBg" fORMat="reference" /><!--滑块背景图片-->
        <attr name="m_blockColor" format="color" /><!--滑块颜色-->
        <attr name="m_blockShadowLayer" format="color" /><!--滑块阴影颜色-->
        <attr name="m_proColor" format="color" /><!--进度条颜色-->
        <attr name="m_recColor" format="color" /><!--矩形背景色-->
        <attr name="m_circleSize" format="integer" /><!--圆角角度值-->
    </declare-styleable>
</resources>

自定义View代码


public class MyCheckView extends View {

    private boolean isBlockArea = false;
    private boolean isMove = false;
    private boolean isFinish = false;
    private boolean isDown = false;
    private int mRight;
    private int startX = 0;

    
    private final int blockSize = SizeUtils.dp2px(5);

    
    private int m_blockColor = Color.WHITE;//默认滑块颜色
    private int m_blockShadowLayer = Color.parseColor("#D8D8D8");//默认滑块阴影色
    private int m_proColor = Color.parseColor("#ff3159");//默认进度条颜色
    private int m_recColor = Color.parseColor("#D8D8D8");//默认矩形颜色
    private int blockDrawableId;//默认滑块背景图

    
    private final Paint recPaint = new Paint();

    
    private final Paint proPaint = new Paint();

    
    private final Paint blockPaint = new Paint();

    
    private int circleSize = SizeUtils.dp2px(20);

    
    private float parentWidth = 0f;

    
    private int proHeight;

    
    private final int DEFAULT_HEIGHT = SizeUtils.dp2px(45);

    
    private final int blockWidth = SizeUtils.dp2px(60);

    
    private int dX;

    
    private int mX;

    
    private FinishListener finishListener;

    public void setFinishListener(FinishListener finishListener) {
        this.finishListener = finishListener;
    }

    public MyCheckView(@NonNull Context context) {
        super(context);
        init();
    }

    public MyCheckView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initParams(context, attrs);
        init();
    }

    public MyCheckView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initParams(context, attrs);
        init();
    }

    
    private void initParams(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyCheckView);
        if (typedArray != null) {
            //获取滑块背景图片
            blockDrawableId = typedArray.getResourceId(R.styleable.MyCheckView_m_blockBg, -1);
            //获取滑块颜色
            m_blockColor = typedArray.getColor(R.styleable.MyCheckView_m_blockColor, m_blockColor);
            //滑块阴影色
            m_blockShadowLayer = typedArray.getColor(R.styleable.MyCheckView_m_blockColor, m_blockShadowLayer);
            //进度条颜色
            m_proColor = typedArray.getColor(R.styleable.MyCheckView_m_blockColor, m_proColor);
            //矩形颜色
            m_recColor = typedArray.getColor(R.styleable.MyCheckView_m_blockColor, m_recColor);
            //圆角角度值
            circleSize = typedArray.getInt(R.styleable.MyCheckView_m_blockColor, circleSize);
            typedArray.recycle();
        }
    }

    
    private void init() {
        //设置矩形背景色
        recPaint.setColor(m_recColor);
        recPaint.setStyle(Paint.Style.FILL);
        recPaint.setAntiAlias(true);

        //设置进度条背景色
        proPaint.setColor(m_proColor);
        proPaint.setStyle(Paint.Style.FILL);
        recPaint.setAntiAlias(true);

        //判断是否使用了背景图
        if (blockDrawableId != -1) {
            //设置滑块背景色
            blockPaint.setColor(m_blockColor);
            blockPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            blockPaint.setAntiAlias(true);
            //给滑块添加阴影
            blockPaint.setShadowLayer(35, 1, 1, m_blockShadowLayer);
        } else {
            blockPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            blockPaint.setAntiAlias(true);
        }
    }

    public void blockReset() {
        mX = 0;
        reset(startX);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        parentWidth = getMyWSize(widthMeasureSpec);
        proHeight = getMyHSize(heightMeasureSpec);
        setMeasuredDimension((int) parentWidth, proHeight);

    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(canvas canvas) {
        super.onDraw(canvas);
        //绘制矩形
        RectF rectF = new RectF();
        rectF.left = 1;
        rectF.right = parentWidth - 1;
        rectF.top = 1;
        rectF.bottom = proHeight - 1;
        //绘制圆角矩形
        canvas.drawRoundRect(rectF, circleSize, circleSize, recPaint);

        if (isMove || isDown) {
            //绘制进度条
            RectF rectP = new RectF();
            rectP.left = 1;
            rectP.right = blockWidth + blockSize + mX;
            rectP.top = 1;
            rectP.bottom = proHeight - 1;
            canvas.drawRoundRect(rectP, circleSize, circleSize, proPaint);
        }

        //绘制滑块
        RectF rectB = new RectF();
        rectB.left = blockSize + mX;
        rectB.right = blockWidth + mX;
        rectB.top = blockSize;
        rectB.bottom = proHeight - blockSize;

        mRight = (int) rectB.right;

        //判断是否使用了背景图
        if (blockDrawableId != -1) {
            //绘制背景图
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), blockDrawableId);
            Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
            canvas.drawBitmap(bitmap, rect, rectB, blockPaint);
        } else {
            //绘制滑块
            canvas.drawRoundRect(rectB, circleSize, circleSize, blockPaint);
        }

    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                dX = (int) event.getX();
                int dY = (int) event.getY();
                int top = getTop();
                int bottom = getBottom();
                //判断区域是否为滑块
                if (dX > blockSize && dX < blockWidth && dY > blockSize && dY < (bottom - top)) {
                    isBlockArea = true;
                }
                return true;
            case MotionEvent.ACTION_MOVE:

                if (isBlockArea) {
                    mX = (int) event.getX() - dX;
                    //设置范围
                    if ((blockWidth + blockSize + mX) < parentWidth && (blockSize + mX) >= blockSize) {
                        //计算偏移量
                        invalidate();
                        startX = (int) event.getX() - blockWidth / 2;
                    } else if ((blockSize + mX) >= blockSize) {
                        //超出复位
                        mX = (int) parentWidth - blockWidth - blockSize;
                        invalidate();
                    }
                    isMove = true;
                }
                return true;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                isBlockArea = false;
                isFinish = mRight == parentWidth - blockSize;
                if (isFinish) {
                    //监听回调
                    if (finishListener != null) {
                        finishListener.finish();
                    }
                }
                if (!isFinish && isMove) {
                    reset(startX);
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    
    private void reset(int start) {

        ValueAnimator valueAnimator = ValueAnimator.ofInt(start, 0);
        valueAnimator.setDuration(500);
        valueAnimator.start();
        valueAnimator.addUpdateListener(animation -> {
            mX = (int) animation.getAnimatedValue();
            //刷新
            invalidate();
        });
        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                isMove = false;
                isFinish = false;
                startX = 0;
            }
        });
    }

    
    private int getMyWSize(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;//确切大小,所以将得到的尺寸给view
        } else if (specMode == MeasureSpec.AT_MOST) {
            result = Math.min(getScreenWidth() - 20, specSize);
        } else {
            result = getScreenWidth() - 20;
        }
        return result;
    }

    
    private int getMyHSize(int measureSpec) {
        int result;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;//确切大小,所以将得到的尺寸给view
        } else if (specMode == MeasureSpec.AT_MOST) {
            result = Math.min(DEFAULT_HEIGHT, specSize);
        } else {
            result = DEFAULT_HEIGHT - 20;
        }
        return result;
    }

    
    private int getScreenWidth() {
        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.widthPixels;
    }

    
    public interface FinishListener {
        void finish();
    }

}

使用方法


<com.guanwei.globe.view.MyCheckView
        Android:id="@+id/checkView"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:m_blockBg="@mipmap/block" />

到此这篇关于Android自定View实现滑动验证效果的文章就介绍到这了,更多相关Android自定View滑动验证内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android自定View实现滑动验证效果的代码

本文链接: https://www.lsjlt.com/news/160857.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android自定View实现滑动验证效果的代码
    效果图 自定义属性代码 <?xml version="1.0" encoding="utf-8"?> <resources> &...
    99+
    2024-04-02
  • Android如何自定View实现滑动验证效果
    本篇内容主要讲解“Android如何自定View实现滑动验证效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android如何自定View实现滑动验证效果”吧!效果图自定义属性代码<xm...
    99+
    2023-06-22
  • Android自定义view实现滑动解锁效果
    本文实例为大家分享了Android自定义view实现滑动解锁的具体代码,供大家参考,具体内容如下 1. 需求如下: 近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。 2. ...
    99+
    2024-04-02
  • Android自定义View实现竖向滑动回弹效果
    本文实例为大家分享了Android自定义View实现滑动回弹的具体代码,供大家参考,具体内容如下 前言 Android 页面滑动的时候的回弹效果 一、关键代码 public clas...
    99+
    2024-04-02
  • Android自定义滑动验证条的示例代码
    本文介绍了Android自定义滑动验证条的示例代码,分享给大家,具体如下:*注:不知道为什么,h6的标签在这里没用了,所以我也只能用Markdown的语法来写了项目地址:https://github.com/994866755/handso...
    99+
    2023-05-30
    android 滑动验证条 roi
  • Android如何实现View滑动效果
    这篇文章给大家分享的是有关Android如何实现View滑动效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、View的滑动简介View的滑动是Android实现自定义控件的基础,同时在开发中我们也难免会遇到...
    99+
    2023-06-14
  • Android怎么自定义View实现竖向滑动回弹效果
    这篇文章主要介绍“Android怎么自定义View实现竖向滑动回弹效果”,在日常操作中,相信很多人在Android怎么自定义View实现竖向滑动回弹效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Andro...
    99+
    2023-06-30
  • Android自定义View实现随机数验证码
    目录前言效果自定义 View 分类步骤1.自定义属性2.添加构造方法3.在构造里获取自定义样式4.重写 onDraw 计算坐标绘制5.重写 onMeasure 测量宽高6.设置点击事...
    99+
    2024-04-02
  • Android view如何实现滑动悬浮固定效果
    这篇文章主要介绍了Android view如何实现滑动悬浮固定效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.背景在项目开发过程中,有时候会碰到这样的需求:在滑动的过程...
    99+
    2023-05-30
    android
  • Android自定义View实现拖动自动吸边效果
    本文实例为大家分享了Android自定义View实现拖动自动吸边的具体代码,供大家参考,具体内容如下 自定义View,一是为了满足设计需求,二是开发者进阶的标志之一。随心所欲就是我等...
    99+
    2024-04-02
  • Android实现View滑动效果的6种方法
    本文实例为大家分享了Android实现View滑动效果的具体代码,供大家参考,具体内容如下 一、View的滑动简介 View的滑动是Android实现自定义控件的基础,同时在开发中我...
    99+
    2024-04-02
  • 怎么在Android中通过自定义view实现滑动解锁效果
    怎么在Android中通过自定义view实现滑动解锁效果?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。自定义view如下@SuppressLint("Clicka...
    99+
    2023-06-15
  • Android自定义View实现动画效果详解
    目录帧动画补间动画属性动画帧动画 帧动画就是给定一个完整动画的所有关键帧,由大脑想象中间的变化过程的一种动画。 <xml version="1.0" encoding="utf...
    99+
    2023-02-02
    Android自定义View实现动画 Android 动画 Android自定义View
  • Android怎么自定义View实现随机数验证码
    本篇内容介绍了“Android怎么自定义View实现随机数验证码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!效果自定义 View 分类简单...
    99+
    2023-07-02
  • Java实现滑动验证码的示例代码
    目录1.效果演示2.后端代码控制层工具类3.前端页面功能:java实现滑动验证码 项目是采用springboot,maven 开发工具:采用idea 1.效果演示 2.后端代码...
    99+
    2024-04-02
  • Android 自定义view实现水波纹动画效果
    在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她;在这样的关键时候,身子板就一定得硬了,可千万别说不行,爷们儿怎么能说不行呢;好了...
    99+
    2023-05-31
    android 水波纹 roi
  • Android自定义view利用PathEffect实现动态效果
    目录前言一、首先介绍下PathEffect的一些子类二、看看子类具体的一些代码三、案例实现(CornerPathEffect,PathDashPathEffect,ComposePa...
    99+
    2024-04-02
  • Android自定义View实现扫描效果
    本文实例为大家分享了Android自定义View实现扫描效果的具体代码,供大家参考,具体内容如下 演示效果如下: 实现内容: 1、控制动画是竖向或者横向 2、控制动画初始是从底部/...
    99+
    2024-04-02
  • Android自定义View实现时钟效果
    本文实例为大家分享了Android自定义View实现时钟效果的具体代码,供大家参考,具体内容如下 自定义时钟 初学自定义View,先画一个不太成熟的时钟(甚至只有秒针) 时钟效果 ...
    99+
    2024-04-02
  • Android自定义SeekBar实现滑动验证且不可点击
    最近公司因为短信接口被盗刷的比较严重,需要做一个类似于淘宝的滑动验证,用于特定环境,以增加一层保障。拿到需求首先想到的是自定义ViewGroup来实现,里面放一个seekbar和Te...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作