Android进阶之自定义View实战(二)九宫格手势解锁实现

本文是Android自定义View系列的第二篇,通过九宫格手势解锁View实例,介绍如何处理用户手势操作。文章分析了手势锁的要素,包括格子状态、绘制元素和触摸事件逻辑,并提供了Block和GestureLockView的实现代码,帮助读者掌握自定义View中触摸事件的处理。
摘要由CSDN通过智能技术生成

一.引言

在上篇博客Android进阶之自定义View实战(一)仿iOS UISwitch控件实现中我们主要介绍了自定义View的最基本的实现方法。作为自定义View的入门篇,仅仅介绍了Canvas的基本使用方法,而对用户交互层面仅仅处理了单击事件接口,在实际的业务中,常常涉及到手势操作,本篇博客以九宫格手势解锁View为例,来说明自定义View如何根据需求处理用户的手势操作。虽然九宫格手势解锁自定义View网上资料有很多,实现原理大同小异,但这里我只是根据自己觉得最优的思路来实现它,目的是让更多的初学者能看清我的思想,更快的掌握它的套路。话不多说,先看效果图,本人纯种工科男,颜色大家看看就好~_~!(ps:as的录屏效果有一半屏幕是花的,所以上图片将就一下。。);
1.手指滑动状态
手指滑动状态
2.手指释放后,校验失败
手指释放后,校验失败
3.手指释放后,校验成功
手指锁释放后,校验成功

二.案例分析

根据上面的三张图,可以看出手势锁有下面几个要素:
1.九宫格阵列状态,每个格子有三种状态:空闲、击中、校验失败、校验成功,其中击中状态是在手指移动过程中产生,后面的校验状态是手指释放后产生。格子状态的改变都在View的触摸事件里处理。
2.九宫格的绘制元素,每个格子有半透明大圆、深色小圆、三角;在移动过程中的手指路径,包括两个:格子与格子之间的连线和路径的”尾巴”:动态探测线。
3.触摸事件所需要处理的逻辑主要有每个格子的状态处理和路径规划。
1>根据手指的位置,确定击中的节点,在down和move事件改变它的状态;
2>在move事件中,探测击中的节点,如果探测到则绘制连线,否则绘制探测线。
3>在up或者cancel事件中,取消探测线,并根据击中的节点校验密码,更新状态,计算三角的方向,重绘节点。

三.范例代码

1.通过第二节的分析,格子(Block)是这个View的基本构成单元,包含状态、位置、大小半径、三角等元素,触摸事件的处理都是真的Block的处理。Block代码:

package com.star.gesturelock;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;

/**
 * 一个阵列的基本组成单元
 * Created by kakaixcm on 16/6/7.
 */
public class Block {
   
    float mCenterPointX;//圆心x
    float mCenterPointY;//圆心y
    float mBigRadius;//大圆半径
    float mLittleRadius;//小圆半径
    BlockSate mState = BlockSate.IDLE;//默认空闲

    int mId;//索引

    //空闲状态颜色
    int mIdleBigCircleColor = Color.parseColor("#110000ff");
    int mIdleLittleCircleColor = Color.parseColor("#0000ff");

    //选中状态颜色
    int mHittedBigCircleColor = Color.parseColor("#1100ff00");
    int mHittedLittleCircleColor = Color.parseColor("#00ff00");

    //密码通过的颜色
    int mSuccessBigCircleColor = Color.parseColor("#1100ff00");
    int mSuccessdLittleCircleColor = Color.parseColor("#00ff00");

    //密码错误时的颜色
    int mErroBigCircleColor = Color.parseColor("#11ff0000");
    int mErroLittleCircleColor = Color.parseColor("#ff0000");

    //三角
    Path mArrow = new Path();
    //三角指向角度,水平向右为0度,顺时针方向为正
    double mArrowAngle;

    public void setArrowAngle(double angle){
        mArrowAngle = angle;
    }

    public void drawArrow(Canvas canvas, Paint paint){
        //没有松手,则不画三角
        if(mState != BlockSate.SUCCESS && mState != BlockSate.ERRO){
            return;
        }

        float arrowLen = (mBigRadius - mLittleRadius)*0.5f;
        float arrowLeftX = mCenterPointX + mLittleRadius + (mBigRadius - mLittleRadius - arrowLen)/2;
        float arrowRightX = arrowLeftX + arrowLen;
        float topY = mCenterPointY - arrowLen;
        float bottomY = mCenterPointY + arrowLen;
        mArrow.moveTo(arrowRightX, mCenterPointY);
        mArrow.lineTo(arrowLeftX, topY);
        mArrow.lineTo(arrowLeftX, bottomY);
        mArrow.close();

        canvas.save();
        canvas.rotate((float) mArrowAngle, mCenterPointX, mCenterPointY);
        canv
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值