转载请表明出处:http://blog.csdn.net/forsxj/article/details/45221933
废话不多说,上效果图,先是高仿:
下面是正版的:
大体上实现了支付宝钱包九宫格解锁的效果,只是在细节上还是有一些不一样的,比如颜色、九宫格的尺寸等。这些不是本文的重点,下面我们就来具体的实现这个Demo。
步骤如下:
一,准备所用的四张图片
当然不用图片而全部用代码绘制也是可以的。
二,自定义控件,绘制出九宫格布局。
三,监听触摸事件,绘制相应的九宫格图形。
四,密码输入结束后判断密码是否正确,并回调执行相应的代码
下面我们首先开始自定义我们的九宫格控件:
public class NinePointLockerView extends View
{
//四种图片
private Bitmap mBitmap_Point_Selected;
private Bitmap mBitmap_Point_Normal;
private Bitmap mBitmap_Point_Error;
private Bitmap mBitmap_Point_Arrow;
//两种连接线的颜色
private final int mLineColor_Blue = 0xff0066cc;
private final int mLineColor_Red = 0xffff0000;
//三种画笔
private Paint mPaint_Line_Blue;
private Paint mPaint_Line_Red;
private Paint mPaint_Clear_Line;//用于清空已经选择为密码的九宫格内的连接线
//从左上至右下为0-8
private Bitmap[][] mNinePointBitmap = new Bitmap[3][3];
private Rect[][] mNinePointRect = new Rect[3][3];
private LockerCircle[][] mNineLockerCircles = new LockerCircle[3][3];
//获取的输入密码列表,顺序同上
private ArrayList<Password> mInputPasswords = new ArrayList<>();
private int mGap = 40;//每两个九宫格图片之间的距离是2个mGap,且距离边框的距离是1个mGap
private int mRadius = 0;//九宫格圆形图片半径
private int[] mPassword = {
0, 1, 2, 5, 8};//预设的密码
private Matrix mRotateMatrix = new Matrix();//用于旋转红色指示箭头
private Rect mBitmapArrowRect = new Rect();//旋转后的红色箭头图片区域
private OnPasswordCorrectListener mOnPasswordCorrectListener;//监听器接口
//三种状态
private static final int STATUS_MOVING = 0;
private static final int STATUS_RESET = 1;
private static final int STATUS_PASSWORD_FAIL = 2;
private int mStatus = STATUS_RESET;//当前状态
//当前触摸点的坐标
private double mCurrentX;
private double mCurrentY;
//用于绘制最终显示的图片
private Canvas mCanvas_Temp;
private Bitmap mBitmap_Temp;
public interface OnPasswordCorrectListener
{
void onPasswordCorrect();
void onPasswordWrong();
}
public NinePointLockerView(Context context)
{
this(context, null, 0);
}
public NinePointLockerView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public NinePointLockerView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
initPaint_Canvas();
}
//初始化画笔和Canvas
private void initPaint_Canvas()
{
mBitmap_Point_Normal = BitmapFactory.decodeResource(getResources(), R.mipmap.point_normal);
mBitmap_Point_Selected = BitmapFactory.decodeResource(getResources(), R.mipmap.point_selected);
mBitmap_Point_Error = BitmapFactory.decodeResource(getResources(), R.mipmap.point_error);
mBitmap_Point_Arrow = BitmapFactory.decodeResource(getResources(), R.mipmap.point_arrow);
mPaint_Line_Blue = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint_Line_Blue.setStyle(Paint.Style.STROKE);
mPaint_Line_Blue.setStrokeWidth(4);
mPaint_Line_Blue.setColor(mLineColor_Blue);
mPaint_Line_Red = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint_Line_Red.setStrokeWidth(4);
mPaint_Line_Red.setStyle(Paint.Style.STROKE);
mPaint_Line_Red.setColor(mLineColor_Red);
mPaint_Clear_Line = new Paint();
mPaint_Clear_Line.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint_Clear_Line.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mCanvas_Temp = new Canvas();
}
这段代码主要是声明并初始化后面要用到的成员变量。为了提高View的绘制效率,最好不要在onDraw函数中进行变量的初始化工作,初始化工作尽量在绘制之前完成。下面开始对View进行测量:
@Override