天天看點

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

這篇來分享一下繪制手勢密碼的實作(主要是設定手勢密碼、校驗手勢密碼):

一、大緻界面介紹:

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995
仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

                       圖1                                                                                                                 圖2                                                      

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995
仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

                         圖3                                                                                                                圖4

圖1:手勢密碼繪制界面 【主要是繪制上方的9個提示圖示和9個宮格密碼圖示】

圖2:設定手勢密碼 【監聽手勢的輸入,touchevent的事件處理,擷取輸入的手勢密碼,同時顯示在上方的提示區域】

圖3:再繪制一次,兩次密碼不一緻提示界面 【這裡在實作的時候,錯誤提示文字加了“左右晃動的動畫”,錯誤路徑顔色标記為紅色】

圖4:校驗手勢密碼,輸入的密碼錯誤,給予紅色路徑+錯誤文字提示

二、實作思路:

1. 正上方的提示區域,用一個類(lockindicator.java)來實作,自定義view來繪制9個提示圖示;

2. 手勢密碼繪制區域,用一個類(gesturecontentview.java)來實作,它繼承自viewgroup裡面, 添加9個imageview來表示圖示, 在onlayout()方法中設定它們的位置;

3. 手勢路徑繪制, 用一個類(gesturedrawline.java)來實作,複寫ontouchevent()方法,在這個方法裡面監聽touchevent事件: action_down、action_move、action_up事件,來繪制手勢連接配接不同點之間的路徑;

4. 9個點的對象,用一個類(gesturepoint.java)來實作,儲存它的位置、狀态、背景圖檔等相關資訊;

5. 手勢密碼的擷取,判斷手指目前的位置,根據滑動路徑經過的點,按順序儲存繪制的點的順序(這裡的點順序從上到下分别是:1,2,3,4,5,6,7,8,9),不能有重複的點。

三、代碼實作步驟:

1.要用一個類來表示這9個點中的第一個點。裡面保留有目前點的上下左右的各個位置等屬性

2.自定義groupview,用來裝9個點,9個點的顯示是通過imageview。複寫onlayout這個方法,讓點按需求排列

3.定義一個可以畫線的view,複寫ontouchevent方法,在這個方法裡面進行畫直線的操作

4.判斷使用者手指目前的位置,取出目前的位置去與那9個點中的每個點的位置進行比較,如果使用者點的位置在某一個點之内,那麼當那個點置換背景圖檔。

具體實作代碼如下:

1. lockindicator.java 圖案提示類

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

package com.snda.fund.widget;  

import com.snda.fund.r;  

import android.content.context;  

import android.content.res.typedarray;  

import android.graphics.canvas;  

import android.graphics.paint;  

import android.graphics.paint.style;  

import android.graphics.drawable.drawable;  

import android.os.powermanager;  

import android.text.textutils;  

import android.util.attributeset;  

import android.util.log;  

import android.view.view;  

/** 

 *  

 * 手勢密碼圖案提示 

 * @author wulianghuan 

 * 

 */  

public class lockindicator extends view {  

    private int numrow = 3; // 行  

    private int numcolum = 3; // 列  

    private int patternwidth = 40;  

    private int patternheight = 40;  

    private int f = 5;  

    private int g = 5;  

    private int strokewidth = 3;  

    private paint paint = null;  

    private drawable patternnoraml = null;  

    private drawable patternpressed = null;  

    private string lockpassstr; // 手勢密碼  

    public lockindicator(context paramcontext) {  

        super(paramcontext);  

    }  

    public lockindicator(context paramcontext, attributeset paramattributeset) {  

        super(paramcontext, paramattributeset, 0);  

        paint = new paint();  

        paint.setantialias(true);  

        paint.setstrokewidth(strokewidth);  

        paint.setstyle(paint.style.stroke);  

        patternnoraml = getresources().getdrawable(r.drawable.lock_pattern_node_normal);  

        patternpressed = getresources().getdrawable(r.drawable.lock_pattern_node_pressed);  

        if (patternpressed != null) {  

            patternwidth = patternpressed.getintrinsicwidth();  

            patternheight = patternpressed.getintrinsicheight();  

            this.f = (patternwidth / 4);  

            this.g = (patternheight / 4);  

            patternpressed.setbounds(0, 0, patternwidth, patternheight);  

            patternnoraml.setbounds(0, 0, patternwidth, patternheight);  

        }  

    @override  

    protected void ondraw(canvas canvas) {  

        if ((patternpressed == null) || (patternnoraml == null)) {  

            return;  

        // 繪制3*3的圖示  

        for (int i = 0; i < numrow; i++) {  

            for (int j = 0; j < numcolum; j++) {  

                paint.setcolor(-16777216);  

                int i1 = j * patternheight + j * this.g;  

                int i2 = i * patternwidth + i * this.f;  

                canvas.save();  

                canvas.translate(i1, i2);  

                string curnum = string.valueof(numcolum * i + (j + 1));  

                if (!textutils.isempty(lockpassstr)) {  

                    if (lockpassstr.indexof(curnum) == -1) {  

                        // 未選中  

                        patternnoraml.draw(canvas);  

                    } else {  

                        // 被選中  

                        patternpressed.draw(canvas);  

                    }  

                } else {  

                    // 重置狀态  

                    patternnoraml.draw(canvas);  

                }  

                canvas.restore();  

            }  

    protected void onmeasure(int paramint1, int paramint2) {  

        if (patternpressed != null)  

            setmeasureddimension(numcolum * patternheight + this.g  

                    * (-1 + numcolum), numrow * patternwidth + this.f  

                    * (-1 + numrow));  

    /** 

     * 請求重新繪制 

     * @param paramstring 手勢密碼字元序列 

     */  

    public void setpath(string paramstring) {  

        lockpassstr = paramstring;  

        invalidate();  

}  

2. gesturecontentview.java  手勢密碼容器類

它繼承viewgroup,通過addview()方法添加子viewe,手勢密碼的9個輸入點(gesturepoint)、gesturedrawline手勢密碼路徑都放在這個容器當中,下面是它的具體實作方法:

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

package com.wujay.fund.widget;  

import java.util.arraylist;  

import java.util.list;  

import android.view.viewgroup;  

import android.widget.imageview;  

import com.wujay.fund.r;  

import com.wujay.fund.common.apputil;  

import com.wujay.fund.entity.gesturepoint;  

import com.wujay.fund.widget.gesturedrawline.gesturecallback;  

 * 手勢密碼容器類 

public class gesturecontentview extends viewgroup {  

    private int basenum = 6;  

    private int[] screendispaly;  

     * 每個點區域的寬度 

    private int blockwidth;  

     * 聲明一個集合用來封裝坐标集合 

    private list<gesturepoint> list;  

    private context context;  

    private boolean isverify;  

    private gesturedrawline gesturedrawline;  

     * 包含9個imageview的容器,初始化 

     * @param context 

     * @param isverify 是否為校驗手勢密碼 

     * @param password 使用者傳入密碼 

     * @param callback 手勢繪制完畢的回調 

    public gesturecontentview(context context, boolean isverify, string password, gesturecallback callback) {  

        super(context);  

        screendispaly = apputil.getscreendispaly(context);  

        blockwidth = screendispaly[0]/3;  

        this.list = new arraylist<gesturepoint>();  

        this.context = context;  

        this.isverify = isverify;  

        // 添加9個圖示  

        addchild();  

        // 初始化一個可以畫線的view  

        gesturedrawline = new gesturedrawline(context, list, isverify, password, callback);  

    private void addchild(){  

        for (int i = 0; i < 9; i++) {  

            imageview image = new imageview(context);  

            image.setbackgroundresource(r.drawable.gesture_node_normal);  

            this.addview(image);  

            invalidate();  

            // 第幾行  

            int row = i / 3;  

            // 第幾列  

            int col = i % 3;  

            // 定義點的每個屬性  

            int leftx = col*blockwidth+blockwidth/basenum;  

            int topy = row*blockwidth+blockwidth/basenum;  

            int rightx = col*blockwidth+blockwidth-blockwidth/basenum;  

            int bottomy = row*blockwidth+blockwidth-blockwidth/basenum;  

            gesturepoint p = new gesturepoint(leftx, rightx, topy, bottomy, image,i+1);  

            this.list.add(p);  

    public void setparentview(viewgroup parent){  

        // 得到螢幕的寬度  

        int width = screendispaly[0];  

        layoutparams layoutparams = new layoutparams(width, width);  

        this.setlayoutparams(layoutparams);  

        gesturedrawline.setlayoutparams(layoutparams);  

        parent.addview(gesturedrawline);  

        parent.addview(this);  

    protected void onlayout(boolean changed, int l, int t, int r, int b) {  

        for (int i = 0; i < getchildcount(); i++) {  

            //第幾行  

            int row = i/3;  

            //第幾列  

            int col = i%3;  

            view v = getchildat(i);  

            v.layout(col*blockwidth+blockwidth/basenum, row*blockwidth+blockwidth/basenum,   

                    col*blockwidth+blockwidth-blockwidth/basenum, row*blockwidth+blockwidth-blockwidth/basenum);  

    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {  

        super.onmeasure(widthmeasurespec, heightmeasurespec);  

        // 周遊設定每個子view的大小  

            v.measure(widthmeasurespec, heightmeasurespec);  

     * 保留路徑delaytime時間長 

     * @param delaytime 

    public void cleardrawlinestate(long delaytime) {  

        gesturedrawline.cleardrawlinestate(delaytime);  

3. gesturedrawline.java 手勢密碼路徑繪制類

根據ontouchevent方法的不同僚件,action_down、action_move、action_up分别處理不同的邏輯。

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

import java.util.hashmap;  

import java.util.map;  

import com.wujay.fund.common.constants;  

import android.graphics.bitmap;  

import android.graphics.color;  

import android.graphics.porterduff;  

import android.os.handler;  

import android.util.pair;  

import android.view.motionevent;  

import android.widget.toast;  

 * 手勢密碼路徑繪制 

public class gesturedrawline extends view {  

    private int mov_x;// 聲明起點坐标  

    private int mov_y;  

    private paint paint;// 聲明畫筆  

    private canvas canvas;// 畫布  

    private bitmap bitmap;// 位圖  

    private list<gesturepoint> list;// 裝有各個view坐标的集合  

    private list<pair<gesturepoint, gesturepoint>> linelist;// 記錄畫過的線  

    private map<string, gesturepoint> autocheckpointmap;// 自動選中的情況點  

    private boolean isdrawenable = true; // 是否允許繪制  

     * 螢幕的寬度和高度 

     * 手指目前在哪個point内 

    private gesturepoint currentpoint;  

     * 使用者繪圖的回調 

    private gesturecallback callback;  

     * 使用者目前繪制的圖形密碼 

    private stringbuilder passwordsb;  

     * 是否為校驗 

     * 使用者傳入的password 

    private string password;  

    public gesturedrawline(context context, list<gesturepoint> list, boolean isverify,  

            string password, gesturecallback callback) {  

        paint = new paint(paint.dither_flag);// 建立一個畫筆  

        bitmap = bitmap.createbitmap(screendispaly[0], screendispaly[0], bitmap.config.argb_8888); // 設定位圖的寬高  

        canvas = new canvas();  

        canvas.setbitmap(bitmap);  

        paint.setstyle(style.stroke);// 設定非填充  

        paint.setstrokewidth(10);// 筆寬5像素  

        paint.setcolor(color.rgb(245, 142, 33));// 設定預設連線顔色  

        paint.setantialias(true);// 不顯示鋸齒  

        this.list = list;  

        this.linelist = new arraylist<pair<gesturepoint, gesturepoint>>();  

        initautocheckpointmap();  

        this.callback = callback;  

        // 初始化密碼緩存  

        this.passwordsb = new stringbuilder();  

        this.password = password;  

    private void initautocheckpointmap() {  

        autocheckpointmap = new hashmap<string,gesturepoint>();  

        autocheckpointmap.put("1,3", getgesturepointbynum(2));  

        autocheckpointmap.put("1,7", getgesturepointbynum(4));  

        autocheckpointmap.put("1,9", getgesturepointbynum(5));  

        autocheckpointmap.put("2,8", getgesturepointbynum(5));  

        autocheckpointmap.put("3,7", getgesturepointbynum(5));  

        autocheckpointmap.put("3,9", getgesturepointbynum(6));  

        autocheckpointmap.put("4,6", getgesturepointbynum(5));  

        autocheckpointmap.put("7,9", getgesturepointbynum(8));  

    private gesturepoint getgesturepointbynum(int num) {  

        for (gesturepoint point : list) {  

            if (point.getnum() == num) {  

                return point;  

        return null;  

    // 畫位圖  

        // super.ondraw(canvas);  

        canvas.drawbitmap(bitmap, 0, 0, null);  

    // 觸摸事件  

    public boolean ontouchevent(motionevent event) {  

        if (isdrawenable == false) {  

            // 當期不允許繪制  

            return true;  

        switch (event.getaction()) {  

        case motionevent.action_down:  

            mov_x = (int) event.getx();  

            mov_y = (int) event.gety();  

            // 判斷目前點選的位置是處于哪個點之内  

            currentpoint = getpointat(mov_x, mov_y);  

            if (currentpoint != null) {  

                currentpoint.setpointstate(constants.point_state_selected);  

                passwordsb.append(currentpoint.getnum());  

            // canvas.drawpoint(mov_x, mov_y, paint);// 畫點  

            break;  

        case motionevent.action_move:  

            clearscreenanddrawlist();  

            // 得到目前移動位置是處于哪個點内  

            gesturepoint pointat = getpointat((int) event.getx(), (int) event.gety());  

            // 代表目前使用者手指處于點與點之前  

            if (currentpoint == null && pointat == null) {  

                return true;  

            } else {// 代表使用者的手指移動到了點上  

                if (currentpoint == null) {// 先判斷目前的point是不是為null  

                    // 如果為空,那麼把手指移動到的點指派給currentpoint  

                    currentpoint = pointat;  

                    // 把currentpoint這個點設定選中為true;  

                    currentpoint.setpointstate(constants.point_state_selected);  

                    passwordsb.append(currentpoint.getnum());  

            if (pointat == null || currentpoint.equals(pointat) || constants.point_state_selected == pointat.getpointstate()) {  

                // 點選移動區域不在圓的區域,或者目前點選的點與目前移動到的點的位置相同,或者目前點選的點處于選中狀态  

                // 那麼以目前的點中心為起點,以手指移動位置為終點畫線  

                canvas.drawline(currentpoint.getcenterx(), currentpoint.getcentery(), event.getx(), event.gety(), paint);// 畫線  

            } else {  

                // 如果目前點選的點與目前移動到的點的位置不同  

                // 那麼以前前點的中心為起點,以手移動到的點的位置畫線  

                canvas.drawline(currentpoint.getcenterx(), currentpoint.getcentery(), pointat.getcenterx(), pointat.getcentery(), paint);// 畫線  

                pointat.setpointstate(constants.point_state_selected);  

                // 判斷是否中間點需要選中  

                gesturepoint betweenpoint = getbetweencheckpoint(currentpoint, pointat);  

                if (betweenpoint != null && constants.point_state_selected != betweenpoint.getpointstate()) {  

                    // 存在中間點并且沒有被選中  

                    pair<gesturepoint, gesturepoint> pair1 = new pair<gesturepoint, gesturepoint>(currentpoint, betweenpoint);  

                    linelist.add(pair1);  

                    passwordsb.append(betweenpoint.getnum());  

                    pair<gesturepoint, gesturepoint> pair2 = new pair<gesturepoint, gesturepoint>(betweenpoint, pointat);  

                    linelist.add(pair2);  

                    passwordsb.append(pointat.getnum());  

                    // 設定中間點選中  

                    betweenpoint.setpointstate(constants.point_state_selected);  

                    // 指派目前的point;  

                    pair<gesturepoint, gesturepoint> pair = new pair<gesturepoint, gesturepoint>(currentpoint, pointat);  

                    linelist.add(pair);  

        case motionevent.action_up:// 當手指擡起的時候  

            if (isverify) {  

                // 手勢密碼校驗  

                // 清掉螢幕上所有的線,隻畫上集合裡面儲存的線  

                if (password.equals(passwordsb.tostring())) {  

                    // 代表使用者繪制的密碼手勢與傳入的密碼相同  

                    callback.checkedsuccess();  

                    // 使用者繪制的密碼與傳入的密碼不同。  

                    callback.checkedfail();  

                callback.ongesturecodeinput(passwordsb.tostring());  

        default:  

        return true;  

     * 指定時間去清除繪制的狀态 

     * @param delaytime 延遲執行時間 

        if (delaytime > 0) {  

            // 繪制紅色提示路線  

            isdrawenable = false;  

            drawerrorpathtip();  

        new handler().postdelayed(new clearstaterunnable(), delaytime);  

     * 清除繪制狀态的線程 

    final class clearstaterunnable implements runnable {  

        public void run() {  

            // 重置passwordsb  

            passwordsb = new stringbuilder();  

            // 清空儲存點的集合  

            linelist.clear();  

            // 重新繪制界面  

            for (gesturepoint p : list) {  

                p.setpointstate(constants.point_state_normal);  

            isdrawenable = true;  

     * 通過點的位置去集合裡面查找這個點是包含在哪個point裡面的 

     *  

     * @param x 

     * @param y 

     * @return 如果沒有找到,則傳回null,代表使用者目前移動的地方屬于點與點之間 

    private gesturepoint getpointat(int x, int y) {  

            // 先判斷x  

            int leftx = point.getleftx();  

            int rightx = point.getrightx();  

            if (!(x >= leftx && x < rightx)) {  

                // 如果為假,則跳到下一個對比  

                continue;  

            int topy = point.gettopy();  

            int bottomy = point.getbottomy();  

            if (!(y >= topy && y < bottomy)) {  

            // 如果執行到這,那麼說明目前點選的點的位置在周遊到點的位置這個地方  

            return point;  

    private gesturepoint getbetweencheckpoint(gesturepoint pointstart, gesturepoint pointend) {  

        int startnum = pointstart.getnum();  

        int endnum = pointend.getnum();  

        string key = null;  

        if (startnum < endnum) {  

            key = startnum + "," + endnum;  

        } else {  

            key = endnum + "," + startnum;  

        return autocheckpointmap.get(key);  

     * 清掉螢幕上所有的線,然後畫出集合裡面的線 

    private void clearscreenanddrawlist() {  

        canvas.drawcolor(color.transparent, porterduff.mode.clear);  

        for (pair<gesturepoint, gesturepoint> pair : linelist) {  

            canvas.drawline(pair.first.getcenterx(), pair.first.getcentery(),  

                    pair.second.getcenterx(), pair.second.getcentery(), paint);// 畫線  

     * 校驗錯誤/兩次繪制不一緻提示 

    private void drawerrorpathtip() {  

        paint.setcolor(color.rgb(154, 7, 21));// 設定預設線路顔色  

            pair.first.setpointstate(constants.point_state_wrong);  

            pair.second.setpointstate(constants.point_state_wrong);  

    public interface gesturecallback {  

        /** 

         * 使用者設定/輸入了手勢密碼 

         */  

        public abstract void ongesturecodeinput(string inputcode);  

         * 代表使用者繪制的密碼與傳入的密碼相同 

        public abstract void checkedsuccess();  

         * 代表使用者繪制的密碼與傳入的密碼不相同 

        public abstract void checkedfail();  

4.gestureeditactivity.java 手勢密碼設定界面

手勢密碼設定

代碼如下:

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

package com.wujay.fund;  

import android.app.activity;  

import android.content.dialoginterface;  

import android.content.intent;  

import android.os.bundle;  

import android.text.html;  

import android.view.keyevent;  

import android.view.view.onclicklistener;  

import android.view.animation.animation;  

import android.view.animation.animationutils;  

import android.widget.framelayout;  

import android.widget.textview;  

import com.wujay.fund.widget.gesturecontentview;  

import com.wujay.fund.widget.lockindicator;  

 * 手勢密碼設定界面 

public class gestureeditactivity extends activity implements onclicklistener {  

    /** 手機号碼*/  

    public static final string param_phone_number = "param_phone_number";  

    /** 意圖 */  

    public static final string param_intent_code = "param_intent_code";  

    /** 首次提示繪制手勢密碼,可以選擇跳過 */  

    public static final string param_is_first_advice = "param_is_first_advice";  

    private textview mtexttitle;  

    private textview mtextcancel;  

    private lockindicator mlockindicator;  

    private textview mtexttip;  

    private framelayout mgesturecontainer;  

    private gesturecontentview mgesturecontentview;  

    private textview mtextreset;  

    private string mparamsetupcode = null;  

    private string mparamphonenumber;  

    private boolean misfirstinput = true;  

    private string mfirstpassword = null;  

    private string mconfirmpassword = null;  

    private int mparamintentcode;  

    public void oncreate(bundle savedinstancestate) {  

        super.oncreate(savedinstancestate);  

        setcontentview(r.layout.activity_gesture_edit);  

        setupviews();  

        setuplisteners();  

    private void setupviews() {  

        mtexttitle = (textview) findviewbyid(r.id.text_title);  

        mtextcancel = (textview) findviewbyid(r.id.text_cancel);  

        mtextreset = (textview) findviewbyid(r.id.text_reset);  

        mtextreset.setclickable(false);  

        mlockindicator = (lockindicator) findviewbyid(r.id.lock_indicator);  

        mtexttip = (textview) findviewbyid(r.id.text_tip);  

        mgesturecontainer = (framelayout) findviewbyid(r.id.gesture_container);  

        // 初始化一個顯示各個點的viewgroup  

        mgesturecontentview = new gesturecontentview(this, false, "", new gesturecallback() {  

            @override  

            public void ongesturecodeinput(string inputcode) {  

                if (!isinputpassvalidate(inputcode)) {  

                    mtexttip.settext(html.fromhtml("<font color='#c70c1e'>最少連結4個點, 請重新輸入</font>"));  

                    mgesturecontentview.cleardrawlinestate(0l);  

                    return;  

                if (misfirstinput) {  

                    mfirstpassword = inputcode;  

                    updatecodelist(inputcode);  

                    mtextreset.setclickable(true);  

                    mtextreset.settext(getstring(r.string.reset_gesture_code));  

                    if (inputcode.equals(mfirstpassword)) {  

                            toast.maketext(gestureeditactivity.this, "設定成功", toast.length_short).show();  

                        mgesturecontentview.cleardrawlinestate(0l);  

                        gestureeditactivity.this.finish();  

                        mtexttip.settext(html.fromhtml("<font color='#c70c1e'>與上一次繪制不一緻,請重新繪制</font>"));  

                        // 左右移動動畫  

                        animation shakeanimation = animationutils.loadanimation(gestureeditactivity.this, r.anim.shake);  

                        mtexttip.startanimation(shakeanimation);  

                        // 保持繪制的線,1.5秒後清除  

                        mgesturecontentview.cleardrawlinestate(1300l);  

                misfirstinput = false;  

            public void checkedsuccess() {  

            public void checkedfail() {  

        });  

        // 設定手勢解鎖顯示到哪個布局裡面  

        mgesturecontentview.setparentview(mgesturecontainer);  

        updatecodelist("");  

    private void setuplisteners() {  

        mtextcancel.setonclicklistener(this);  

        mtextreset.setonclicklistener(this);  

    private void updatecodelist(string inputcode) {  

        // 更新選擇的圖案  

        mlockindicator.setpath(inputcode);  

    public void onclick(view v) {  

        switch (v.getid()) {  

        case r.id.text_cancel:  

            this.finish();  

        case r.id.text_reset:  

            misfirstinput = true;  

            updatecodelist("");  

            mtexttip.settext(getstring(r.string.set_gesture_pattern));  

    private boolean isinputpassvalidate(string inputpassword) {  

        if (textutils.isempty(inputpassword) || inputpassword.length() < 4) {  

            return false;  

5. gestureverifyactivity.java 手勢密碼校驗界面

仿支付寶手勢密碼 源碼下載下傳位址:http://download.csdn.net/detail/wulianghuan/8115995

import android.app.dialog;  

import android.content.dialoginterface.onclicklistener;  

import android.widget.relativelayout;  

 * 手勢繪制/校驗界面 

public class gestureverifyactivity extends activity implements android.view.view.onclicklistener {  

    private relativelayout mtoplayout;  

    private imageview mimguserlogo;  

    private textview mtextphonenumber;  

    private textview mtextforget;  

    private textview mtextother;  

    private long mexittime = 0;  

        setcontentview(r.layout.activity_gesture_verify);  

        obtainextradata();  

    private void obtainextradata() {  

        mparamphonenumber = getintent().getstringextra(param_phone_number);  

        mparamintentcode = getintent().getintextra(param_intent_code, 0);  

        mtoplayout = (relativelayout) findviewbyid(r.id.top_layout);  

        mimguserlogo = (imageview) findviewbyid(r.id.user_logo);  

        mtextphonenumber = (textview) findviewbyid(r.id.text_phone_number);  

        mtextforget = (textview) findviewbyid(r.id.text_forget_gesture);  

        mtextother = (textview) findviewbyid(r.id.text_other_account);  

        mgesturecontentview = new gesturecontentview(this, true, "1235789",  

                new gesturecallback() {  

                    @override  

                    public void ongesturecodeinput(string inputcode) {  

                    public void checkedsuccess() {  

                        toast.maketext(gestureverifyactivity.this, "密碼正确", 1000).show();  

                        gestureverifyactivity.this.finish();  

                    public void checkedfail() {  

                        mtexttip.setvisibility(view.visible);  

                        mtexttip.settext(html  

                                .fromhtml("<font color='#c70c1e'>密碼錯誤</font>"));  

                        animation shakeanimation = animationutils.loadanimation(gestureverifyactivity.this, r.anim.shake);  

                });  

        mtextforget.setonclicklistener(this);  

        mtextother.setonclicklistener(this);  

    private string getprotectedmobile(string phonenumber) {  

        if (textutils.isempty(phonenumber) || phonenumber.length() < 11) {  

            return "";  

        stringbuilder builder = new stringbuilder();  

        builder.append(phonenumber.subsequence(0,3));  

        builder.append("****");  

        builder.append(phonenumber.subsequence(7,11));  

        return builder.tostring();  

以上是手勢密碼實作的關鍵代碼,我把項目中的子產品代碼整理出來,建立了一個project,供大家分享和交流

源碼下載下傳位址: