国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義UI手勢密碼改進版源碼下載

2019-12-12 04:51:56
字體:
來源:轉載
供稿:網友

在之前文章的鋪墊下,再為大家分享一篇:Android手勢密碼,附源碼下載,不要錯過。

源碼下載:http://xiazai.VeVB.COm/201610/yuanma/androidLock(VeVB.COm).rar

先看第一張圖片的布局文件

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical"  android:gravity="center_horizontal" >   <TextView  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_marginTop="40dip"  android:textSize="24sp"  android:text="手勢密碼" />   <Button  android:id="@+id/btn_set_lockpattern"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_marginTop="50dip"  android:text="設置手勢密碼" />   <Button  android:id="@+id/btn_verify_lockpattern"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_marginTop="10dip"  android:text="校驗手勢密碼" />   <TextView  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_marginTop="10dip"  android:text="密碼圖案是大2"/>  </LinearLayout> 

再看上面布局的java代碼
MainActivity

package com.wujay.fund;  import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;  public class MainActivity extends Activity implements OnClickListener {  private Button mBtnSetLock;  private Button mBtnVerifyLock;   @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  setUpView();  setUpListener();  }   private void setUpView() {  mBtnSetLock = (Button) findViewById(R.id.btn_set_lockpattern);  mBtnVerifyLock = (Button) findViewById(R.id.btn_verify_lockpattern);  }   private void setUpListener() {  mBtnSetLock.setOnClickListener(this);  mBtnVerifyLock.setOnClickListener(this);  }   @Override  public void onClick(View v) {  switch (v.getId()) {  case R.id.btn_set_lockpattern:   startSetLockPattern();   break;  case R.id.btn_verify_lockpattern:   startVerifyLockPattern();   break;  default:   break;  }  }   private void startSetLockPattern() {  Intent intent = new Intent(MainActivity.this, GestureEditActivity.class);  startActivity(intent);  }   private void startVerifyLockPattern() {  Intent intent = new Intent(MainActivity.this, GestureVerifyActivity.class);  startActivity(intent);  } } 

另外看下工具類和bean類
AppUtil

package com.wujay.fund.common;  import android.content.Context; import android.view.WindowManager;  public class AppUtil {  public static int[] getScreenDispaly(Context context) {  WindowManager windowManager = (WindowManager) context   .getSystemService(Context.WINDOW_SERVICE);  int width = windowManager.getDefaultDisplay().getWidth();// 手機屏幕的寬度  int height = windowManager.getDefaultDisplay().getHeight();// 手機屏幕的高度  int result[] = { width, height };  return result;  } } 

再看9宮格的單位bean類
GesturePoint

package com.wujay.fund.entity;   import com.wujay.fund.R; import com.wujay.fund.common.Constants;  import android.widget.ImageView;  public class GesturePoint {  /**  * 狀態值  */  private int pointState;   /** 代表這個Point對象代表的數字,從1開始(直接感覺從1開始)*/  private int num;  private int leftX;  private int rightX;  private int topY;  private int bottomY;  private ImageView image;   private int centerX;  private int centerY;  public GesturePoint(int leftX, int rightX, int topY, int bottomY,   ImageView image, int num) {  super();  this.leftX = leftX;  this.rightX = rightX;  this.topY = topY;  this.bottomY = bottomY;  this.image = image;   this.centerX = (leftX + rightX) / 2;  this.centerY = (topY + bottomY) / 2;   this.num = num;  }   public int getLeftX() {  return leftX;  }   public void setLeftX(int leftX) {  this.leftX = leftX;  }   public int getRightX() {  return rightX;  }   public void setRightX(int rightX) {  this.rightX = rightX;  }   public int getTopY() {  return topY;  }   public void setTopY(int topY) {  this.topY = topY;  }   public int getBottomY() {  return bottomY;  }   public void setBottomY(int bottomY) {  this.bottomY = bottomY;  }   public ImageView getImage() {  return image;  }   public void setImage(ImageView image) {  this.image = image;  }   public int getCenterX() {  return centerX;  }   public void setCenterX(int centerX) {  this.centerX = centerX;  }   public int getCenterY() {  return centerY;  }   public void setCenterY(int centerY) {  this.centerY = centerY;  }   public int getPointState() {  return pointState;  }   public void setPointState(int state) {  pointState = state;  switch (state) {  case Constants.POINT_STATE_NORMAL:   this.image.setBackgroundResource(R.drawable.gesture_node_normal);   break;  case Constants.POINT_STATE_SELECTED:   this.image.setBackgroundResource(R.drawable.gesture_node_pressed);   break;  case Constants.POINT_STATE_WRONG:   this.image.setBackgroundResource(R.drawable.gesture_node_wrong);   break;  default:   break;  }  }   public int getNum() {  return num;  }   public void setNum(int num) {  this.num = num;  }   @Override  public int hashCode() {  final int prime = 31;  int result = 1;  result = prime * result + bottomY;  result = prime * result + ((image == null) ? 0 : image.hashCode());  result = prime * result + leftX;  result = prime * result + rightX;  result = prime * result + topY;  return result;  }   @Override  public boolean equals(Object obj) {  if (this == obj)   return true;  if (obj == null)   return false;  if (getClass() != obj.getClass())   return false;  GesturePoint other = (GesturePoint) obj;  if (bottomY != other.bottomY)   return false;  if (image == null) {   if (other.image != null)   return false;  } else if (!image.equals(other.image))   return false;  if (leftX != other.leftX)   return false;  if (rightX != other.rightX)   return false;  if (topY != other.topY)   return false;  return true;  }   @Override  public String toString() {  return "Point [leftX=" + leftX + ", rightX=" + rightX + ", topY="   + topY + ", bottomY=" + bottomY + "]";  } } 

再看每個點位的3種狀態
Constants

package com.wujay.fund.common; public class Constants { public static final int POINT_STATE_NORMAL = 0; // 正常狀態 public static final int POINT_STATE_SELECTED = 1; // 按下狀態 public static final int POINT_STATE_WRONG = 2; // 錯誤狀態 } 

再看來繪制密碼的界面
activity_gesture_edit.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="#48423D" >   <RelativeLayout  android:id="@+id/top_layout"  android:layout_width="match_parent"  android:layout_height="46dip"  android:background="#000000"  android:paddingLeft="20dip"  android:paddingRight="20dip"  android:layout_alignParentTop="true" >   <TextView   android:id="@+id/text_title"   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:layout_centerInParent="true"   android:gravity="center"   android:text="@string/setup_gesture_code"   android:textSize="20sp"   android:textColor="#ffffff" />  </RelativeLayout>   <LinearLayout  android:id="@+id/gesture_tip_layout"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:layout_below="@id/top_layout"  android:gravity="center"  android:orientation="vertical" >    <TextView   android:id="@+id/text_tip"   android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:gravity="center_horizontal"   android:text="@string/set_gesture_pattern"   android:textColor="#F98F12"   android:layout_marginTop="10dip" />  </LinearLayout>   <FrameLayout  android:id="@+id/gesture_container"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_below="@id/gesture_tip_layout"  android:layout_gravity="center_horizontal"  android:layout_marginTop="20dip" >  </FrameLayout>   <TextView  android:id="@+id/text_reset"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:gravity="center_horizontal"  android:layout_below="@id/gesture_container"  android:layout_marginTop="20dip"  android:text="@string/set_gesture_pattern_reason"  android:textColor="#816E6A" />  </RelativeLayout> 

再看來繪制密碼的類
GestureEditActivity

package com.wujay.fund;  import com.wujay.fund.R; import android.app.Activity; import android.os.Bundle; import android.text.Html; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.TextView; import android.widget.Toast; import com.wujay.fund.widget.GestureContentView; import com.wujay.fund.widget.GestureDrawline.GestureCallBack;  /**  * 手勢密碼設置界面  */ public class GestureEditActivity extends Activity implements OnClickListener {  // 2次繪制手勢密碼不正確的提示語  private TextView mTextTip;  // 手勢密碼繪制區域  private FrameLayout mGestureContainer;  private GestureContentView mGestureContentView;  // 重新設置手勢密碼  private TextView mTextReset;  // 是否是第一次繪制密碼鎖  private boolean mIsFirstInput = true;  // 初次繪制完畢密碼鎖,生成的密碼  private String mFirstPassword = null;   @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_gesture_edit);  setUpViews();  setUpListeners();  }   /**  * 判斷初次繪制完畢生成的密碼判斷 判斷是不是為空 判斷密碼數量是不是小于4  */  private boolean isInputPassValidate(String inputPassword) {  if (TextUtils.isEmpty(inputPassword) || inputPassword.length() < 4) {   return false;  }  return true;  }   private void setUpViews() {  // 重新設置手勢密碼  mTextReset = (TextView) findViewById(R.id.text_reset);  // 默認不可點擊  mTextReset.setClickable(false);  // 2次繪制手勢密碼不正確的提示語  mTextTip = (TextView) findViewById(R.id.text_tip);  // 手勢密碼繪制區域  mGestureContainer = (FrameLayout) findViewById(R.id.gesture_container);  /**   * 初始化一個顯示各個點的viewGroup GestureContentView(Context context, boolean   * isVerify, String passWord, GestureCallBack callBack)   */  mGestureContentView = new GestureContentView(this, false, "",   new GestureCallBack() {    @Override    public void onGestureCodeInput(String inputCode) {    // 驗證輸入的圖案密碼--如果密碼為null。或者密碼個數少于4個    if (!isInputPassValidate(inputCode)) {     mTextTip.setText(Html      .fromHtml("<font color='#c70c1e'>最少鏈接4個點, 請重新輸入</font>"));     // 立刻清楚畫的線段     mGestureContentView.clearDrawlineState(0L);     return;    }    if (mIsFirstInput) {     // 第一次輸入密碼--保存第一次輸入的密碼,在進行跟第二次判斷     mFirstPassword = inputCode;     // 第一次輸入完畢后,立刻清楚畫的線段     mGestureContentView.clearDrawlineState(0L);     // 設置可以重新設置密碼鎖的狀態按鈕     mTextReset.setClickable(true);     mTextReset      .setText(getString(R.string.reset_gesture_code));    } else {     if (inputCode.equals(mFirstPassword)) {     Toast.makeText(GestureEditActivity.this,      "設置成功", Toast.LENGTH_SHORT).show();     mGestureContentView.clearDrawlineState(0L);     GestureEditActivity.this.finish();     } else {     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;    }     @Override    public void checkedSuccess() {     }     @Override    public void checkedFail() {     }   });  // 設置手勢解鎖顯示到哪個布局里面  mGestureContentView.setParentView(mGestureContainer);  }   /*****************************************************/  private void setUpListeners() {  mTextReset.setOnClickListener(this);  }   @Override  public void onClick(View v) {  switch (v.getId()) {  case R.id.text_reset:   mIsFirstInput = true;   mTextTip.setText(getString(R.string.set_gesture_pattern));   break;  default:   break;  }  }  } 

GestureContentView

package com.wujay.fund.widget;  import java.util.ArrayList; import java.util.List; import android.content.Context; import android.view.View; 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 GestureDrawline gestureDrawline;   /************************************************************************  * 包含9個ImageView的容器,初始化  *  * @param context  * @param isVerify  *  是否為校驗手勢密碼  * @param passWord  *  用戶傳入密碼  * @param callBack  *  手勢繪制完畢的回調  */  private int[] screenDispaly;  // 將屏幕寬度分成3份  private int blockWidth;  // 9個點位的集合  private List<GesturePoint> list;  // 環境  private Context context;  // 是否需要校驗密碼  private boolean isVerify;   public GestureContentView(Context context, boolean isVerify,   String passWord, GestureCallBack callBack) {  super(context);  // 獲取屏幕寬度  screenDispaly = AppUtil.getScreenDispaly(context);  // 獲取屏幕寬度的1/3  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);  }   /**  * 添加9個圓點的圖標  */  // 用來計算2個圓心之間的一半距離大小  private int baseNum = 6;   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();   // 第幾行---012 0 ,345 1, 678 2--   int row = i / 3;   // 第幾列---012 012 , 345 012 , 678 012   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);   // 添加9個圓點圖標   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);  }   /************************************** 繪制圓點位操作 ****************************************/  @Override  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);  }  }   @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  // 遍歷設置每個子view的大小  for (int i = 0; i < getChildCount(); i++) {   View v = getChildAt(i);   v.measure(widthMeasureSpec, heightMeasureSpec);  }  }   /**  * 對外暴露一個方法---用于清楚密碼鎖上的線段 保留路徑delayTime時間長  *  * @param delayTime  */  public void clearDrawlineState(long delayTime) {  gestureDrawline.clearDrawlineState(delayTime);  }  } 

GestureDrawline

package com.wujay.fund.widget;  import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.wujay.fund.common.AppUtil; import com.wujay.fund.common.Constants; import com.wujay.fund.entity.GesturePoint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.PorterDuff; import android.os.Handler; import android.util.Log; import android.util.Pair; import android.view.MotionEvent; import android.view.View; import android.widget.Toast;  /**  * 手勢密碼路徑繪制  *  */ public class GestureDrawline extends View {  private int mov_x;// 聲明起點坐標  private int mov_y;   private Map<String, GesturePoint> autoCheckPointMap;// 自動選中的情況點  private boolean isDrawEnable = true; // 是否允許繪制   /**********************************************************************  * 構造函數  */  private int[] screenDispaly;  private Paint paint;// 聲明畫筆  private Canvas canvas;// 畫布  private Bitmap bitmap;// 位圖  private List<GesturePoint> list;// 裝有各個view坐標的集合  private List<Pair<GesturePoint, GesturePoint>> lineList;// 記錄畫過的線  private StringBuilder passWordSb;  private boolean isVerify;  private String passWord;  private GestureCallBack callBack;   public GestureDrawline(Context context, List<GesturePoint> list,   boolean isVerify, String passWord, GestureCallBack callBack) {  super(context);  screenDispaly = AppUtil.getScreenDispaly(context);  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.isVerify = isVerify;  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;  }   /**********************************************************  * 畫位圖  */  @Override  protected void onDraw(Canvas canvas) {  canvas.drawBitmap(bitmap, 0, 0, paint);   }   /**  * 通過點的位置去集合里面查找這個點是包含在哪個Point里面的  *  * @return 如果沒有找到,則返回null,代表用戶當前移動的地方屬于點與點之間  */  private GesturePoint getPointAt(int x, int y) {   for (GesturePoint point : list) {   // 先判斷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)) {   // 如果為假,則跳到下一個對比   continue;   }    // 如果執行到這,那么說明當前點擊的點的位置在遍歷到點的位置這個地方   return point;  }   return null;  }   /**  * 清掉屏幕上所有的線,然后畫出集合里面的線  */  private void clearScreenAndDrawList() {  canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);  for (Pair<GesturePoint, GesturePoint> pair : lineList) {   // drawLine(float startX, float startY, float stopX, float stopY,   // Paint paint)   canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(),    pair.second.getCenterX(), pair.second.getCenterY(), paint);// 畫線  }  }   /**  * 判斷是否中間點需要選中  *  * @param pointStart  * @param pointEnd  * @return  */  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 GesturePoint currentPoint;   @Override  public boolean onTouchEvent(MotionEvent event) {  if (isDrawEnable == false) {   // 如果圓點圖片呈現紅色的底片--也就是二次繪制錯誤,在沒有清楚繪制的線段的情況下,不再允許繪制線條   return true;  }  paint.setColor(Color.rgb(245, 142, 33));// 設置默認連線顏色  switch (event.getAction()) {  case MotionEvent.ACTION_DOWN:   // 鼠標按下后,獲取手指點位的xy坐標   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());   }   invalidate();   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)) {   // 點擊移動區域不在圓的區域,或者當前點擊的點與當前移動到的點的位置相同   // 那么以當前的點中心為起點,以手指移動位置為終點畫線   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;    currentPoint = pointAt;   } else {    Pair<GesturePoint, GesturePoint> pair = new Pair<GesturePoint, GesturePoint>(     currentPoint, pointAt);    lineList.add(pair);    passWordSb.append(pointAt.getNum());    // 賦值當前的point;    currentPoint = pointAt;   }   }   invalidate();   break;  case MotionEvent.ACTION_UP:// 當手指抬起的時候   if (isVerify) {   // 手勢密碼校驗   // 清掉屏幕上所有的線,只畫上集合里面保存的線   if (passWord.equals(passWordSb.toString())) {    // 代表用戶繪制的密碼手勢與傳入的密碼相同    callBack.checkedSuccess();   } else {    // 用戶繪制的密碼與傳入的密碼不同。    callBack.checkedFail();   }   } else {   callBack.onGestureCodeInput(passWordSb.toString());   }   break;  default:   break;  }  return true;  }   /************************************  * 校驗錯誤/兩次繪制不一致提示  */  private void drawErrorPathTip() {  canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);  paint.setColor(Color.rgb(154, 7, 21));// 設置默認線路顏色  for (Pair<GesturePoint, GesturePoint> pair : lineList) {   pair.first.setPointState(Constants.POINT_STATE_WRONG);   pair.second.setPointState(Constants.POINT_STATE_WRONG);   canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY(),    pair.second.getCenterX(), pair.second.getCenterY(), paint);// 畫線  }  invalidate();  }   /**  * 指定時間去清除繪制的狀態  *  * @param delayTime  *  延遲執行時間  */  public void clearDrawlineState(long 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();   // 重新繪制界面   clearScreenAndDrawList();   for (GesturePoint p : list) {   p.setPointState(Constants.POINT_STATE_NORMAL);   }   invalidate();   isDrawEnable = true;  }  }   public interface GestureCallBack {   /**   * 用戶設置/輸入了手勢密碼   */  public abstract void onGestureCodeInput(String inputCode);   /**   * 代表用戶繪制的密碼與傳入的密碼相同   */  public abstract void checkedSuccess();   /**   * 代表用戶繪制的密碼與傳入的密碼不相同   */  public abstract void checkedFail();  }  } 

接下來看驗證密碼鎖的布局
activity_gesture_verify.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:background="#48443c" >    <LinearLayout  android:id="@+id/gesture_tip_layout"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:layout_below="@id/top_layout"  android:orientation="vertical"  android:paddingTop="20dip" >    <TextView   android:id="@+id/text_tip"   android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:layout_marginTop="10dip"   android:gravity="center_horizontal"   android:textColor="#000000"   android:visibility="invisible" />  </LinearLayout>   <FrameLayout  android:id="@+id/gesture_container"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:layout_below="@id/gesture_tip_layout" >  </FrameLayout>   </RelativeLayout> 

驗證密碼的代碼實現類
GestureVerifyActivity

package com.wujay.fund;  import com.wujay.fund.R; import com.wujay.fund.widget.GestureContentView; import com.wujay.fund.widget.GestureDrawline.GestureCallBack; import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; import android.text.Html; import android.text.TextUtils; import android.view.KeyEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast;  /**  * 手勢繪制/校驗界面  */ public class GestureVerifyActivity extends Activity{  private TextView mTextTip;  private FrameLayout mGestureContainer;  private GestureContentView mGestureContentView;   @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_gesture_verify);  setUpViews();  }    private void setUpViews() {  //驗證失敗的錯誤提示  mTextTip = (TextView) findViewById(R.id.text_tip);  mGestureContainer = (FrameLayout) findViewById(R.id.gesture_container);    // 初始化一個顯示各個點的viewGroup  mGestureContentView = new GestureContentView(this, true, "12589",   new GestureCallBack() {     @Override    public void onGestureCodeInput(String inputCode) {     }     @Override    public void checkedSuccess() {    mGestureContentView.clearDrawlineState(0L);    Toast.makeText(GestureVerifyActivity.this, "密碼正確", 1000).show();    GestureVerifyActivity.this.finish();    }     @Override    public void checkedFail() {    mGestureContentView.clearDrawlineState(1300L);    mTextTip.setVisibility(View.VISIBLE);    mTextTip.setText(Html     .fromHtml("<font color='#c70c1e'>密碼錯誤</font>"));    // 左右移動動畫    Animation shakeAnimation = AnimationUtils.loadAnimation(GestureVerifyActivity.this, R.anim.shake);    mTextTip.startAnimation(shakeAnimation);    }   });  // 設置手勢解鎖顯示到哪個布局里面  mGestureContentView.setParentView(mGestureContainer);  }   } 

shake.xml

<?xml version="1.0" encoding="utf-8"?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="10" android:duration="120" android:interpolator="@android:anim/cycle_interpolator" android:repeatMode="restart" android:repeatCount="2"/> 

推薦文章:

Android自定義UI手勢密碼簡單版

Android自定義UI手勢密碼改進版

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 寻甸| 临沭县| 五常市| 额尔古纳市| 花莲市| 武定县| 象州县| 巨野县| 耿马| 梧州市| 招远市| 宝山区| 喀喇沁旗| 西吉县| 珠海市| 康马县| 瑞金市| 屯门区| 沙雅县| 开封县| 申扎县| 措勤县| 龙南县| 石泉县| 桦甸市| 河源市| 齐齐哈尔市| 麦盖提县| 射阳县| 敦化市| 九江县| 乐平市| 富川| 荥阳市| 庆阳市| 新干县| 吴江市| 安达市| 五大连池市| 潜山县| 土默特左旗|