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

首頁 > 系統 > Android > 正文

Android APP數字解鎖實例詳解

2019-12-12 04:50:32
字體:
來源:轉載
供稿:網友

Android APP數字上鎖

最近抽時間做了下數字解鎖的功能,手機有數字解鎖,App也可以做到,避免某些應用隱私泄漏,一下就是實現效果圖:

序言:這兩天老大給了個任務,說是做一個仿ios的數字鎖屏界面,心想著這種東西網上應該有挺多的,然后就先百度了一把,誰知道案例好像少的可憐,然后帶著懷疑的心態去下載了千辛萬苦找到的“源碼”,看里面寫的,然后自己有點眉目了,就自己借著“源碼”的思路自己實現了一把,見上圖。

思路:

這里我們可以看成兩部分,一部分是上面的輸入的,另一部分是底部的按鍵。
先來看上面那部分,我們可以看成是TextView,然后響應下面按鍵的動作。下面這部分,圖中的每個按鈕都需要自己畫出來,難點就是根據第一個按鍵的坐標(第一個坐標我們初始化)算出每個按鍵的坐標,然后根據手指的觸摸屏事件來判斷點擊的是哪個按鍵

接下來我們來看核心代碼:

輸入框部分:

public class PasswordTextView extends TextView{ private final String sing = "*";//密文顯示的內容 private String content = "";//顯示的內容 //文本改變事件回調接口 private OnTextChangedListener onTextChangedListener; /**  * Handler線程對象,用來更新密碼框的顯示內容  * 實現將輸入的內容顯示為密文  */ private Handler handler = new Handler(){  public void handleMessage(android.os.Message msg) {   //密文顯示   PasswordTextView.this.setText(sing);   //回調改變事件接口   if(onTextChangedListener != null){    onTextChangedListener.textChanged(content);   }  }; }; /**  * 構造方法  * @param context  * @param attrs  */ public PasswordTextView(Context context, AttributeSet attrs) {  super(context, attrs); } /**  * 設置文本改變事件監聽  * @param onTextChangedListener  */ public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener){  this.onTextChangedListener = onTextChangedListener; } /**  * 設置密碼框顯示的內容  * @param text  */ public void setTextContent(String text){  //獲得輸入的內容  this.content = text;  if(!TextUtils.isEmpty(text)){   handler.sendEmptyMessage(0);//向Handler發送消息  }else{   this.setText("");  } } /**  * 獲取顯示的內容  * @return  */ public String getTextContent(){  return content; } /**  * 文本改變事件接口  */ public interface OnTextChangedListener{  /**   * 密碼框文本改變時調用   * @param content   */  public void textChanged(String content); }}

下面按鍵部分

public class NumericK eyboard extends View { private int screen_width = 0;// 屏幕的寬度 private float first_x = 0;// 繪制1的x坐標 private float first_y = 0;// 繪制1的y坐標 private float[] xs = new float[3];//聲明數組保存每一列的圓心橫坐標 private float[] ys = new float[4];//聲明數組保存每一排的圓心縱坐標 private float circle_x, circle_y;//點擊處的圓心坐標 private int number = -1;//點擊的數字 private OnNumberClick onNumberClick;//數字點擊事件 /*  * 判斷刷新數據  * -1 不進行數據刷新  * 0 按下刷新  * 1 彈起刷新  */ private int type = -1; /**  * 構造方法  *  * @param context  */ public NumericKeyboard(Context context) {  super(context);  initData(context);// 初始化數據 } public NumericKeyboard(Context context, AttributeSet attrs) {  super(context, attrs);  initData(context);// 初始化數據 } /**  * 設置數字點擊事件  *  * @param onNumberClick  */ public void setOnNumberClick(OnNumberClick onNumberClick) {  this.onNumberClick = onNumberClick; } // 初始化數據 private void initData(Context context) {  // 獲取屏幕的寬度  screen_width = SystemUtils.getSystemDisplay(context)[0];  // 獲取繪制1的x坐標  first_x = screen_width / 4;  // 獲取繪制1的y坐標  first_y = (SystemUtils.getSystemDisplay(context)[1] - SystemUtils.getSystemDisplay(context)[1] / 3) / 4;  //添加每一排的橫坐標  xs[0] = first_x + 10;  xs[1] = first_x * 2 + 10;  xs[2] = first_x * 3 + 10;  //添加每一列的縱坐標  ys[0] = 40 + first_y - 15;  ys[1] = 40 + first_y + first_x - 15;  ys[2] = 40 + first_y + first_x * 2 - 15;  ys[3] = 40 + first_y + first_x * 3 - 15; } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  // 創建畫筆對象  Paint paint = new Paint();  paint.setColor(Color.BLACK);// 設置畫筆顏色  paint.setTextSize(40);// 設置字體大小  paint.setStrokeWidth(2);  // 繪制文本,注意是從坐標開始往上繪制  // 這里較難的就是算坐標  // 繪制第一排1,2,3  canvas.drawText("1", first_x, 40 + first_y, paint);  canvas.drawText("2", first_x * 2, 40 + first_y, paint);  canvas.drawText("3", first_x * 3, 40 + first_y, paint);  // 繪制第2排4,5,6  canvas.drawText("4", first_x, 40 + first_y + first_x, paint);  canvas.drawText("5", first_x * 2, 40 + first_y + first_x, paint);  canvas.drawText("6", first_x * 3, 40 + first_y + first_x, paint);  // 繪制第3排7,8,9  canvas.drawText("7", first_x, 40 + first_y + first_x * 2, paint);  canvas.drawText("8", first_x * 2, 40 + first_y + first_x * 2, paint);  canvas.drawText("9", first_x * 3, 40 + first_y + first_x * 2, paint);  // 繪制第4排0  canvas.drawText("0", first_x * 2, 40 + first_y + first_x * 3, paint);  //為每一個數字繪制一個圓  paint.setColor(Color.WHITE);//設置畫筆顏色  paint.setAntiAlias(true);//設置抗鋸齒  //設置繪制空心圓  paint.setStyle(Paint.Style.STROKE);  //依次繪制第一排的圓  canvas.drawCircle(first_x + 10, 40 + first_y - 15, 70, paint);  canvas.drawCircle(first_x * 2 + 10, 40 + first_y - 15, 70, paint);  canvas.drawCircle(first_x * 3 + 10, 40 + first_y - 15, 70, paint);  //依次繪制第2排的圓  canvas.drawCircle(first_x + 10, 40 + first_y + first_x - 15, 70, paint);  canvas.drawCircle(first_x * 2 + 10, 40 + first_y + first_x - 15, 70, paint);  canvas.drawCircle(first_x * 3 + 10, 40 + first_y + first_x - 15, 70, paint);  //依次繪制第3排的圓  canvas.drawCircle(first_x + 10, 40 + first_y + first_x * 2 - 15, 70, paint);  canvas.drawCircle(first_x * 2 + 10, 40 + first_y + first_x * 2 - 15, 70, paint);  canvas.drawCircle(first_x * 3 + 10, 40 + first_y + first_x * 2 - 15, 70, paint);  //繪制最后一個圓  canvas.drawCircle(first_x * 2 + 10, 40 + first_y + first_x * 3 - 15, 70, paint);  //判斷是否點擊數字(點擊數字產生的漸變效果)  if (circle_x > 0 && circle_y > 0) {   if (type == 0) {//按下刷新    paint.setColor(Color.WHITE);//設置畫筆顏色    paint.setStyle(Paint.Style.FILL_AND_STROKE);//按下的時候繪制實心圓    canvas.drawCircle(circle_x, circle_y, 70, paint);//繪制圓   } else if (type == 1) {//彈起刷新    paint.setColor(Color.WHITE);//設置畫筆顏色    paint.setStyle(Paint.Style.STROKE);//彈起的時候再繪制空心圓    canvas.drawCircle(circle_x, circle_y, 70, paint);//繪制圓    //繪制完成后,重置    circle_x = 0;    circle_y = 0;   }  } } /**  * 獲取觸摸點擊事件  */ @Override public boolean onTouchEvent(MotionEvent event) {  //事件判斷  switch (event.getAction()) {   case MotionEvent.ACTION_DOWN://按下    //判斷點擊的坐標位置    float x = event.getX();//按下時的X坐標    float y = event.getY();//按下時的Y坐標    //判斷點擊的是哪一個數字圓    handleDown(x, y);    return true;   case MotionEvent.ACTION_UP://彈起    type = 1;//彈起刷新    invalidate();//刷新界面    //返回點擊的數字    if (onNumberClick != null && number != -1) {     onNumberClick.onNumberReturn(number);    }    setDefault();//恢復默認    //發送輔助事件    sendAccessEvent(R.string.numeric_keyboard_up);    return true;   case MotionEvent.ACTION_CANCEL://取消    //恢復默認值    setDefault();    return true;  }  return false; } /*  * 恢復默認值  */ private void setDefault() {  circle_x = 0;  circle_y = 0;  type = -1;  number = -1;  sendAccessEvent(R.string.numeric_keyboard_cancel); } /*  * 設置輔助功能描述  */ private void sendAccessEvent(int resId) {  //設置描述  setContentDescription(getContext().getString(resId));  //發送輔助事件  sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);  setContentDescription(null); } /*  * 判斷點擊的是哪一個數字圓  */ private void handleDown(float x, float y) {  //判斷點擊的是那一列的數據  if (xs[0] - 70 <= x && x <= xs[0] + 70) {//第一列   //獲取點擊處的圓心橫坐標   circle_x = xs[0];   //判斷點擊的是哪一排   if (ys[0] - 70 <= y && ys[0] + 70 >= y) {//第1排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[0];    number = 1;//設置點擊的數字   } else if (ys[1] - 70 <= y && ys[1] + 70 >= y) {//第2排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[1];    number = 4;//設置點擊的數字   } else if (ys[2] - 70 <= y && ys[2] + 70 >= y) {//第3排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[2];    number = 7;//設置點擊的數字   }  } else if (xs[1] - 70 <= x && x <= xs[1] + 70) {//第2列   //獲取點擊處的圓心橫坐標   circle_x = xs[1];   //判斷點擊的是哪一排   if (ys[0] - 70 <= y && ys[0] + 70 >= y) {//第1排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[0];    number = 2;//設置點擊的數字   } else if (ys[1] - 70 <= y && ys[1] + 70 >= y) {//第2排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[1];    number = 5;//設置點擊的數字   } else if (ys[2] - 70 <= y && ys[2] + 70 >= y) {//第3排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[2];    number = 8;//設置點擊的數字   } else if (ys[3] - 70 <= y && ys[3] + 70 >= y) {//第4排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[3];    number = 0;//設置點擊的數字   }  } else if (xs[2] - 70 <= x && x <= xs[2] + 70) {//第3列   //獲取點擊處的圓心橫坐標   circle_x = xs[2];   //判斷點擊的是哪一排   if (ys[0] - 70 <= y && ys[0] + 70 >= y) {//第1排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[0];    number = 3;//設置點擊的數字   } else if (ys[1] - 70 <= y && ys[1] + 70 >= y) {//第2排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[1];    number = 6;//設置點擊的數字   } else if (ys[2] - 70 <= y && ys[2] + 70 >= y) {//第3排    //獲取點擊的數字圓的圓心縱坐標    circle_y = ys[2];    number = 9;//設置點擊的數字   }  }  sendAccessEvent(R.string.numeric_keyboard_down);  type = 0;//按下刷新  //繪制點擊時的背景圓  invalidate(); } /**  * 數字點擊事件  */ public interface OnNumberClick {  /**   * 返回點擊的數字   *   * @param number   */  public void onNumberReturn(int number); }}

上面說了,難點在于計算按鍵的位置,在這里我是根據我下載的demo里面的計算方式相應的修改了,如果不明白android屏幕坐標系的同學請看下面的文章:

參考:

android坐標系詳解

Github下載地址:DEMO下載

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永川市| 谷城县| 新丰县| 来凤县| 集贤县| 霍州市| 余干县| 新龙县| 瓦房店市| 泽普县| 五常市| 洮南市| 德安县| 新巴尔虎左旗| 林州市| 潍坊市| 文水县| 兴仁县| 防城港市| 太仆寺旗| 衡水市| 百色市| 奎屯市| 平昌县| 西昌市| 华亭县| 横山县| 阜南县| 晋州市| 海晏县| 玛沁县| 金川县| 永城市| 辽源市| 阿拉尔市| 云南省| 扎赉特旗| 项城市| 屏东市| 藁城市| 大关县|