Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 手勢鎖的實現 讓自己的應用更加安全吧

Android 手勢鎖的實現 讓自己的應用更加安全吧

編輯:關於Android編程

今天偶遇以github上gesturelock關於手勢鎖的一個例子(有興趣的去搜索下看看),於是下載下來研究,無奈基本沒有注釋,代碼上存在一些問題(當設置gravity=center_vertical無法進行手勢選擇,無意中發現的),於是借鑒這位仁兄的代碼,自己重寫寫了一個,修復了一些問題,加入一些基本的自定義屬性,在此先感謝這位兄弟~。

先上圖,默認效果圖:

\


當然可以自定義數量啊,顏色神馬的,自定義效果圖:

\

\

如果你有藝術細胞,可以給我推薦幾個顏色,無奈個人審美有問題~


<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+MaGi1fvM5cu8wrc8L3A+CjxwPmGhotfUtqjS5cHL0ru49lJlbGF0aXZlTGF5b3V0KEdlc3R1cmVMb2NrVmlld0dyb3VwKdTawO/D5rvhuPm+3bSryOu1xMO/0NC1xLj2yv2jrMn6s8m24Lj2R2VzdHVyZUxvY2tWaWV3o6i+zcrHyc/D5tK7uPa49tChyKbIpqOpo6zIu7rzu+HX1LavvfjQ0LK8vtajrMDvw+a1xL/ttsijrLzkvuCjrMTa1LK1xNaxvrajrLz9zbe1xLTz0KHJ8cLttcS2vMrHsNm31rHIyrXP1rXEo6zL+dLUtPO1qLXEyejWw8Tjz7K7trXEuPbK/aOs1rvSqsTjw7vT0MPcvK+/1r7l1qJ+PC9wPgo8cD5ioaJHZXN0dXJlTG9ja1ZpZXfT0Mj9uPbXtMyso6zDu9PQytbWuLSlxfahosrW1ri0pcX2oaK6zcrW1rjMp8bwo6y74bj5vt3V4sj9uPbXtMysu+bWxrK7zay1xNCnufujrNLUvLDMp8bwyrG1xNChvP3Nt9Do0qrQ/deqtcS9x7bIo6y74bj5vt3Tw7un0aHU8bXER2VzdHVyZUxvY2tWaWV3o6y9+NDQvMbL46Os1NpHZXN0dXJlTG9ja1ZpZXdHcm91cM6qw7+49kdlc3R1cmVMb2NrVmlld8no1sM8L3A+CjxwPmOhokdlc3R1cmVMb2NrVmlld0dyb3Vw1vfSqr7NysfF0LbP08O7p0FDVElPTl9NT1ZFo6xBQ1RJT05fRE9XTiCjrCBBQ1RJT05fVVDKsbjEseTRodbQtcRHZXN0dXJlTG9ja1ZpZXe1xNe0zKyjrLKix9K8x8K8z8LAtKOszOG5qdK7tqi1xLvYtfehozwvcD4KPHA+z8LD5r+qyry/tLT6wuujujwvcD4KPHA+MqGiyfnD99K70KnTw7unv8nS1Mno1sO1xMr00NSjujwvcD4KPHA+PHByZSBjbGFzcz0="brush:java;">
用戶可以用過在xml文件中設置這些屬性,改變外觀,最多嘗試次數以及數量等。

3、GestureLockView

package com.zhy.zhy_gesturelockview.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.view.View;

public class GestureLockView extends View
{
	private static final String TAG = "GestureLockView";
	/**
	 * GestureLockView的三種狀態
	 */
	enum Mode
	{
		STATUS_NO_FINGER, STATUS_FINGER_ON, STATUS_FINGER_UP;
	}

	/**
	 * GestureLockView的當前狀態
	 */
	private Mode mCurrentStatus = Mode.STATUS_NO_FINGER;
	
	/**
	 * 寬度
	 */
	private int mWidth;
	/**
	 * 高度
	 */
	private int mHeight;
	/**
	 * 外圓半徑
	 */
	private int mRadius;
	/**
	 * 畫筆的寬度
	 */
	private int mStrokeWidth = 2;

	/**
	 * 圓心坐標
	 */
	private int mCenterX;
	private int mCenterY;
	private Paint mPaint;

	/**
	 * 箭頭(小三角最長邊的一半長度 = mArrawRate * mWidth / 2 )
	 */
	private float mArrowRate = 0.333f;
	private int mArrowDegree = -1;
	private Path mArrowPath;
	/**
	 * 內圓的半徑 = mInnerCircleRadiusRate * mRadus
	 * 
	 */
	private float mInnerCircleRadiusRate = 0.3F;

	/**
	 * 四個顏色,可由用戶自定義,初始化時由GestureLockViewGroup傳入
	 */
	private int mColorNoFingerInner;
	private int mColorNoFingerOutter;
	private int mColorFingerOn;
	private int mColorFingerUp;

	public GestureLockView(Context context , int colorNoFingerInner , int colorNoFingerOutter , int colorFingerOn , int colorFingerUp )
	{
		super(context);
		this.mColorNoFingerInner = colorNoFingerInner;
		this.mColorNoFingerOutter = colorNoFingerOutter;
		this.mColorFingerOn = colorFingerOn;
		this.mColorFingerUp = colorFingerUp;
		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mArrowPath = new Path();

	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		mWidth = MeasureSpec.getSize(widthMeasureSpec);
		mHeight = MeasureSpec.getSize(heightMeasureSpec);

		// 取長和寬中的小值
		mWidth = mWidth < mHeight ? mWidth : mHeight;
		mRadius = mCenterX = mCenterY = mWidth / 2;
		mRadius -= mStrokeWidth / 2;

		// 繪制三角形,初始時是個默認箭頭朝上的一個等腰三角形,用戶繪制結束後,根據由兩個GestureLockView決定需要旋轉多少度
		float mArrowLength = mWidth / 2 * mArrowRate;
		mArrowPath.moveTo(mWidth / 2, mStrokeWidth + 2);
		mArrowPath.lineTo(mWidth / 2 - mArrowLength, mStrokeWidth + 2
				+ mArrowLength);
		mArrowPath.lineTo(mWidth / 2 + mArrowLength, mStrokeWidth + 2
				+ mArrowLength);
		mArrowPath.close();
		mArrowPath.setFillType(Path.FillType.WINDING);

	}

	@Override
	protected void onDraw(Canvas canvas)
	{

		switch (mCurrentStatus)
		{
		case STATUS_FINGER_ON:

			// 繪制外圓
			mPaint.setStyle(Style.STROKE);
			mPaint.setColor(mColorFingerOn);
			mPaint.setStrokeWidth(2);
			canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
			// 繪制內圓
			mPaint.setStyle(Style.FILL);
			canvas.drawCircle(mCenterX, mCenterY, mRadius
					* mInnerCircleRadiusRate, mPaint);
			break;
		case STATUS_FINGER_UP:
			// 繪制外圓
			mPaint.setColor(mColorFingerUp);
			mPaint.setStyle(Style.STROKE);
			mPaint.setStrokeWidth(2);
			canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
			// 繪制內圓
			mPaint.setStyle(Style.FILL);
			canvas.drawCircle(mCenterX, mCenterY, mRadius
					* mInnerCircleRadiusRate, mPaint);

			drawArrow(canvas);

			break;

		case STATUS_NO_FINGER:

			// 繪制外圓
			mPaint.setStyle(Style.FILL);
			mPaint.setColor(mColorNoFingerOutter);
			canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
			// 繪制內圓
			mPaint.setColor(mColorNoFingerInner);
			canvas.drawCircle(mCenterX, mCenterY, mRadius
					* mInnerCircleRadiusRate, mPaint);
			break;

		}

	}

	/**
	 * 繪制箭頭
	 * @param canvas
	 */
	private void drawArrow(Canvas canvas)
	{
		if (mArrowDegree != -1)
		{
			mPaint.setStyle(Paint.Style.FILL);

			canvas.save();
			canvas.rotate(mArrowDegree, mCenterX, mCenterY);
			canvas.drawPath(mArrowPath, mPaint);

			canvas.restore();
		}

	}

	/**
	 * 設置當前模式並重繪界面
	 * 
	 * @param mode
	 */
	public void setMode(Mode mode)
	{
		this.mCurrentStatus = mode;
		invalidate();
	}

	public void setArrowDegree(int degree)
	{
		this.mArrowDegree = degree;
	}

	public int getArrowDegree()
	{
		return this.mArrowDegree;
	}
}

注釋很詳細,主要就是onDraw時,判斷當前狀態,繪制不同的顯示效果;狀態的改變都是GestureLockViewGroup的onTouchEvent中設置的。

4、GestureLockViewGroup

package com.zhy.zhy_gesturelockview.view;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

import com.zhy.zhy_gesturelockview.R;
import com.zhy.zhy_gesturelockview.view.GestureLockView.Mode;

/**
 * 整體包含n*n個GestureLockView,每個GestureLockView間間隔mMarginBetweenLockView,
 * 最外層的GestureLockView與容器存在mMarginBetweenLockView的外邊距
 * 
 * 關於GestureLockView的邊長(n*n): n * mGestureLockViewWidth + ( n + 1 ) *
 * mMarginBetweenLockView = mWidth ; 得:mGestureLockViewWidth = 4 * mWidth / ( 5
 * * mCount + 1 ) 注:mMarginBetweenLockView = mGestureLockViewWidth * 0.25 ;
 * 
 * @author zhy
 * 
 */
public class GestureLockViewGroup extends RelativeLayout
{

	private static final String TAG = "GestureLockViewGroup";
	/**
	 * 保存所有的GestureLockView
	 */
	private GestureLockView[] mGestureLockViews;
	/**
	 * 每個邊上的GestureLockView的個數
	 */
	private int mCount = 4;
	/**
	 * 存儲答案
	 */
	private int[] mAnswer = { 0, 1, 2, 5, 8 };
	/**
	 * 保存用戶選中的GestureLockView的id
	 */
	private List mChoose = new ArrayList();

	private Paint mPaint;
	/**
	 * 每個GestureLockView中間的間距 設置為:mGestureLockViewWidth * 25%
	 */
	private int mMarginBetweenLockView = 30;
	/**
	 * GestureLockView的邊長 4 * mWidth / ( 5 * mCount + 1 )
	 */
	private int mGestureLockViewWidth;

	/**
	 * GestureLockView無手指觸摸的狀態下內圓的顏色
	 */
	private int mNoFingerInnerCircleColor = 0xFF939090;
	/**
	 * GestureLockView無手指觸摸的狀態下外圓的顏色
	 */
	private int mNoFingerOuterCircleColor = 0xFFE0DBDB;
	/**
	 * GestureLockView手指觸摸的狀態下內圓和外圓的顏色
	 */
	private int mFingerOnColor = 0xFF378FC9;
	/**
	 * GestureLockView手指抬起的狀態下內圓和外圓的顏色
	 */
	private int mFingerUpColor = 0xFFFF0000;

	/**
	 * 寬度
	 */
	private int mWidth;
	/**
	 * 高度
	 */
	private int mHeight;

	private Path mPath;
	/**
	 * 指引線的開始位置x
	 */
	private int mLastPathX;
	/**
	 * 指引線的開始位置y
	 */
	private int mLastPathY;
	/**
	 * 指引下的結束位置
	 */
	private Point mTmpTarget = new Point();

	/**
	 * 最大嘗試次數
	 */
	private int mTryTimes = 4;
	/**
	 * 回調接口
	 */
	private OnGestureLockViewListener mOnGestureLockViewListener;

	public GestureLockViewGroup(Context context, AttributeSet attrs)
	{
		this(context, attrs, 0);
	}

	public GestureLockViewGroup(Context context, AttributeSet attrs,
			int defStyle)
	{
		super(context, attrs, defStyle);
		/**
		 * 獲得所有自定義的參數的值
		 */
		TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
				R.styleable.GestureLockViewGroup, defStyle, 0);
		int n = a.getIndexCount();

		for (int i = 0; i < n; i++)
		{
			int attr = a.getIndex(i);
			switch (attr)
			{
			case R.styleable.GestureLockViewGroup_color_no_finger_inner_circle:
				mNoFingerInnerCircleColor = a.getColor(attr,
						mNoFingerInnerCircleColor);
				break;
			case R.styleable.GestureLockViewGroup_color_no_finger_outer_circle:
				mNoFingerOuterCircleColor = a.getColor(attr,
						mNoFingerOuterCircleColor);
				break;
			case R.styleable.GestureLockViewGroup_color_finger_on:
				mFingerOnColor = a.getColor(attr, mFingerOnColor);
				break;
			case R.styleable.GestureLockViewGroup_color_finger_up:
				mFingerUpColor = a.getColor(attr, mFingerUpColor);
				break;
			case R.styleable.GestureLockViewGroup_count:
				mCount = a.getInt(attr, 3);
				break;
			case R.styleable.GestureLockViewGroup_tryTimes:
				mTryTimes = a.getInt(attr, 5);
			default:
				break;
			}
		}

		a.recycle();

		// 初始化畫筆
		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mPaint.setStyle(Paint.Style.STROKE);
		// mPaint.setStrokeWidth(20);
		mPaint.setStrokeCap(Paint.Cap.ROUND);
		mPaint.setStrokeJoin(Paint.Join.ROUND);
		// mPaint.setColor(Color.parseColor("#aaffffff"));
		mPath = new Path();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		mWidth = MeasureSpec.getSize(widthMeasureSpec);
		mHeight = MeasureSpec.getSize(heightMeasureSpec);

		// Log.e(TAG, mWidth + "");
		// Log.e(TAG, mHeight + "");

		mHeight = mWidth = mWidth < mHeight ? mWidth : mHeight;

		// setMeasuredDimension(mWidth, mHeight);

		// 初始化mGestureLockViews
		if (mGestureLockViews == null)
		{
			mGestureLockViews = new GestureLockView[mCount * mCount];
			// 計算每個GestureLockView的寬度
			mGestureLockViewWidth = (int) (4 * mWidth * 1.0f / (5 * mCount + 1));
			//計算每個GestureLockView的間距
			mMarginBetweenLockView = (int) (mGestureLockViewWidth * 0.25);
			// 設置畫筆的寬度為GestureLockView的內圓直徑稍微小點(不喜歡的話,隨便設)
			mPaint.setStrokeWidth(mGestureLockViewWidth * 0.29f);

			for (int i = 0; i < mGestureLockViews.length; i++)
			{
				//初始化每個GestureLockView
				mGestureLockViews[i] = new GestureLockView(getContext(),
						mNoFingerInnerCircleColor, mNoFingerOuterCircleColor,
						mFingerOnColor, mFingerUpColor);
				mGestureLockViews[i].setId(i + 1);
				//設置參數,主要是定位GestureLockView間的位置
				RelativeLayout.LayoutParams lockerParams = new RelativeLayout.LayoutParams(
						mGestureLockViewWidth, mGestureLockViewWidth);

				// 不是每行的第一個,則設置位置為前一個的右邊
				if (i % mCount != 0)
				{
					lockerParams.addRule(RelativeLayout.RIGHT_OF,
							mGestureLockViews[i - 1].getId());
				}
				// 從第二行開始,設置為上一行同一位置View的下面
				if (i > mCount - 1)
				{
					lockerParams.addRule(RelativeLayout.BELOW,
							mGestureLockViews[i - mCount].getId());
				}
				//設置右下左上的邊距
				int rightMargin = mMarginBetweenLockView;
				int bottomMargin = mMarginBetweenLockView;
				int leftMagin = 0;
				int topMargin = 0;
				/**
				 * 每個View都有右外邊距和底外邊距 第一行的有上外邊距 第一列的有左外邊距
				 */
				if (i >= 0 && i < mCount)// 第一行
				{
					topMargin = mMarginBetweenLockView;
				}
				if (i % mCount == 0)// 第一列
				{
					leftMagin = mMarginBetweenLockView;
				}

				lockerParams.setMargins(leftMagin, topMargin, rightMargin,
						bottomMargin);
				mGestureLockViews[i].setMode(Mode.STATUS_NO_FINGER);
				addView(mGestureLockViews[i], lockerParams);
			}

			Log.e(TAG, "mWidth = " + mWidth + " ,  mGestureViewWidth = "
					+ mGestureLockViewWidth + " , mMarginBetweenLockView = "
					+ mMarginBetweenLockView);

		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		int action = event.getAction();
		int x = (int) event.getX();
		int y = (int) event.getY();

		switch (action)
		{
		case MotionEvent.ACTION_DOWN:
			// 重置
			reset();
			break;
		case MotionEvent.ACTION_MOVE:
			mPaint.setColor(mFingerOnColor);
			mPaint.setAlpha(50);
			GestureLockView child = getChildIdByPos(x, y);
			if (child != null)
			{
				int cId = child.getId();
				if (!mChoose.contains(cId))
				{
					mChoose.add(cId);
					child.setMode(Mode.STATUS_FINGER_ON);
					if (mOnGestureLockViewListener != null)
						mOnGestureLockViewListener.onBlockSelected(cId);
					// 設置指引線的起點
					mLastPathX = child.getLeft() / 2 + child.getRight() / 2;
					mLastPathY = child.getTop() / 2 + child.getBottom() / 2;

					if (mChoose.size() == 1)// 當前添加為第一個
					{
						mPath.moveTo(mLastPathX, mLastPathY);
					} else
					// 非第一個,將兩者使用線連上
					{
						mPath.lineTo(mLastPathX, mLastPathY);
					}

				}
			}
			// 指引線的終點
			mTmpTarget.x = x;
			mTmpTarget.y = y;
			break;
		case MotionEvent.ACTION_UP:

			mPaint.setColor(mFingerUpColor);
			mPaint.setAlpha(50);
			this.mTryTimes--;

			// 回調是否成功
			if (mOnGestureLockViewListener != null && mChoose.size() > 0)
			{
				mOnGestureLockViewListener.onGestureEvent(checkAnswer());
				if (this.mTryTimes == 0)
				{
					mOnGestureLockViewListener.onUnmatchedExceedBoundary();
				}
			}

			Log.e(TAG, "mUnMatchExceedBoundary = " + mTryTimes);
			Log.e(TAG, "mChoose = " + mChoose);
			// 將終點設置位置為起點,即取消指引線
			mTmpTarget.x = mLastPathX;
			mTmpTarget.y = mLastPathY;

			// 改變子元素的狀態為UP
			changeItemMode();
			
			// 計算每個元素中箭頭需要旋轉的角度
			for (int i = 0; i + 1 < mChoose.size(); i++)
			{
				int childId = mChoose.get(i);
				int nextChildId = mChoose.get(i + 1);

				GestureLockView startChild = (GestureLockView) findViewById(childId);
				GestureLockView nextChild = (GestureLockView) findViewById(nextChildId);

				int dx = nextChild.getLeft() - startChild.getLeft();
				int dy = nextChild.getTop() - startChild.getTop();
				// 計算角度
				int angle = (int) Math.toDegrees(Math.atan2(dy, dx)) + 90;
				startChild.setArrowDegree(angle);
			}
			break;

		}
		invalidate();
		return true;
	}

	private void changeItemMode()
	{
		for (GestureLockView gestureLockView : mGestureLockViews)
		{
			if (mChoose.contains(gestureLockView.getId()))
			{
				gestureLockView.setMode(Mode.STATUS_FINGER_UP);
			}
		}
	}

	/**
	 * 
	 * 做一些必要的重置
	 */
	private void reset()
	{
		mChoose.clear();
		mPath.reset();
		for (GestureLockView gestureLockView : mGestureLockViews)
		{
			gestureLockView.setMode(Mode.STATUS_NO_FINGER);
			gestureLockView.setArrowDegree(-1);
		}
	}
	/**
	 * 檢查用戶繪制的手勢是否正確
	 * @return
	 */
	private boolean checkAnswer()
	{
		if (mAnswer.length != mChoose.size())
			return false;

		for (int i = 0; i < mAnswer.length; i++)
		{
			if (mAnswer[i] != mChoose.get(i))
				return false;
		}

		return true;
	}
	
	/**
	 * 檢查當前左邊是否在child中
	 * @param child
	 * @param x
	 * @param y
	 * @return
	 */
	private boolean checkPositionInChild(View child, int x, int y)
	{

		//設置了內邊距,即x,y必須落入下GestureLockView的內部中間的小區域中,可以通過調整padding使得x,y落入范圍不變大,或者不設置padding
		int padding = (int) (mGestureLockViewWidth * 0.15);

		if (x >= child.getLeft() + padding && x <= child.getRight() - padding
				&& y >= child.getTop() + padding
				&& y <= child.getBottom() - padding)
		{
			return true;
		}
		return false;
	}

	/**
	 * 通過x,y獲得落入的GestureLockView
	 * @param x
	 * @param y
	 * @return
	 */
	private GestureLockView getChildIdByPos(int x, int y)
	{
		for (GestureLockView gestureLockView : mGestureLockViews)
		{
			if (checkPositionInChild(gestureLockView, x, y))
			{
				return gestureLockView;
			}
		}

		return null;

	}

	/**
	 * 設置回調接口
	 * 
	 * @param listener
	 */
	public void setOnGestureLockViewListener(OnGestureLockViewListener listener)
	{
		this.mOnGestureLockViewListener = listener;
	}

	/**
	 * 對外公布設置答案的方法
	 * 
	 * @param answer
	 */
	public void setAnswer(int[] answer)
	{
		this.mAnswer = answer;
	}

	/**
	 * 設置最大實驗次數
	 * 
	 * @param boundary
	 */
	public void setUnMatchExceedBoundary(int boundary)
	{
		this.mTryTimes = boundary;
	}

	@Override
	public void dispatchDraw(Canvas canvas)
	{
		super.dispatchDraw(canvas);
		//繪制GestureLockView間的連線
		if (mPath != null)
		{
			canvas.drawPath(mPath, mPaint);
		}
		//繪制指引線
		if (mChoose.size() > 0)
		{
			if (mLastPathX != 0 && mLastPathY != 0)
				canvas.drawLine(mLastPathX, mLastPathY, mTmpTarget.x,
						mTmpTarget.y, mPaint);
		}

	}

	public interface OnGestureLockViewListener
	{
		/**
		 * 單獨選中元素的Id
		 * 
		 * @param position
		 */
		public void onBlockSelected(int cId);

		/**
		 * 是否匹配
		 * 
		 * @param matched
		 */
		public void onGestureEvent(boolean matched);

		/**
		 * 超過嘗試次數
		 */
		public void onUnmatchedExceedBoundary();
	}
}

注釋極其詳細,用極其不過分~主要就是onTouchEvent中對用戶選擇的GestureLockView進行判斷,以及改變GestureLockView狀態等。

5、布局文件



    



有興趣的可以自定義屬性,把注釋的代碼添進去就行,當然你也可以什麼都不設置,單純設置寬度和高度,我覺得默認效果也是不錯的 ~

6、調用

package com.zhy.zhy_gesturelockview;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import com.zhy.zhy_gesturelockview.view.GestureLockViewGroup;
import com.zhy.zhy_gesturelockview.view.GestureLockViewGroup.OnGestureLockViewListener;

public class MainActivity extends Activity
{

	private GestureLockViewGroup mGestureLockViewGroup;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mGestureLockViewGroup = (GestureLockViewGroup) findViewById(R.id.id_gestureLockViewGroup);
		mGestureLockViewGroup.setAnswer(new int[] { 1, 2, 3, 4,5 });
		mGestureLockViewGroup
				.setOnGestureLockViewListener(new OnGestureLockViewListener()
				{

					@Override
					public void onUnmatchedExceedBoundary()
					{
						Toast.makeText(MainActivity.this, "錯誤5次...",
								Toast.LENGTH_SHORT).show();
						mGestureLockViewGroup.setUnMatchExceedBoundary(5);
					}

					@Override
					public void onGestureEvent(boolean matched)
					{
						Toast.makeText(MainActivity.this, matched+"",
								Toast.LENGTH_SHORT).show();
					}

					@Override
					public void onBlockSelected(int cId)
					{
					}
				});
	}

}

調用是不是so easy,懶得看代碼又需要用的,可以直接拿來使用,等哪天閒著蛋疼可以研究研究代碼~


ok,有任何問題的留言~


源碼明天到公司貼出來吧,尼瑪,這是拿手機共享的熱點寫的,我的流量啊~~~~還好是1號~




  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved