欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android自定義View實現(xiàn)手勢解鎖

 更新時間:2018年06月04日 17:19:41   作者:qndroid  
這篇文章主要為大家詳細介紹了android自定義View實現(xiàn)手勢解鎖,具有一定的參考價值,感興趣的小伙伴們可以參考一下

有時候為了程序的安全性,我們經(jīng)常要采取一些安全措施,就像我們常用的支付寶那樣,隔一定的時間再回到應用程序時會讓用戶利用手勢去解鎖應用程序,最近由于項目需求,也要求做這樣一個功能,當用戶切出本應用程序15分鐘后回來,讓用戶手勢解鎖,整個需求的難點就在如何實現(xiàn)這個手勢鎖,開始一點頭緒也沒有,沒有一點思路去實現(xiàn)這個手勢解鎖功能,在google了一番后看了一篇非常好的博客后,按照博主的思路的確是可以實現(xiàn)一個十分不錯的手勢鎖View,也參考了下那位大神的代碼,下面是我根據(jù)他的思路和代碼片段實現(xiàn)的一個自定義手勢解鎖 View,先看效果圖.

這是自定義View的初始效果圖:

以下是繪制手勢時的效果圖:

下面是實現(xiàn)的demo代碼:

package com.example.gesturelock; 
 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Timer; 
import java.util.TimerTask; 
 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 
 
import com.example.gesturelock.GestureLockView.OnGestureFinishListener; 
 
public class MyGestureLockView extends View { 
 
  /** 
   * 不同狀態(tài)的畫筆 
   */ 
  private Paint paintNormal; 
  private Paint paintOnTouch; 
  private Paint paintInnerCycle; 
  private Paint paintLines; 
  private Paint paintKeyError; 
 
  private MyCycle[] cycles; 
  private Path linePath = new Path(); 
  private List<Integer> linedCycles = new ArrayList<Integer>(); 
  private OnGestureFinishListener onGestureFinishListener; 
  private String key; 
  private int eventX, eventY; 
  private boolean canContinue = true; 
  private boolean result; 
  private Timer timer; 
 
  /** 
   * 不同狀態(tài)下的色值 
   */ 
  private int OUT_CYCLE_NORMAL = Color.rgb(108, 119, 138); // ������Բ��ɫ 
  private int OUT_CYCLE_ONTOUCH = Color.rgb(025, 066, 103); // ѡ����Բ��ɫ 
  private int INNER_CYCLE_ONTOUCH = Color.rgb(002, 210, 255); // ѡ����Բ��ɫ 
  private int LINE_COLOR = Color.argb(127, 002, 210, 255); // ��������ɫ 
  private int ERROR_COLOR = Color.argb(127, 255, 000, 000); 
 
  public void setOnGestureFinishListener( 
      OnGestureFinishListener onGestureFinishListener) { 
    this.onGestureFinishListener = onGestureFinishListener; 
  } 
 
  public void setKey(String key) { 
    this.key = key; 
  } 
 
  public MyGestureLockView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(); 
  } 
 
  public MyGestureLockView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
  } 
 
  public MyGestureLockView(Context context) { 
    super(context); 
    init(); 
  } 
 
  private void init() { 
 
    paintNormal = new Paint(); 
    paintNormal.setAntiAlias(true); 
    paintNormal.setStrokeWidth(3); 
    paintNormal.setStyle(Paint.Style.STROKE); 
 
    paintOnTouch = new Paint(); 
    paintOnTouch.setAntiAlias(true); 
    paintOnTouch.setStrokeWidth(3); 
    paintOnTouch.setStyle(Paint.Style.STROKE); 
 
    paintInnerCycle = new Paint(); 
    paintInnerCycle.setAntiAlias(true); 
    paintInnerCycle.setStyle(Paint.Style.FILL); 
 
    paintLines = new Paint(); 
    paintLines.setAntiAlias(true); 
    paintLines.setStyle(Paint.Style.STROKE); 
    paintLines.setStrokeWidth(6); 
 
    paintKeyError = new Paint(); 
    paintKeyError.setAntiAlias(true); 
    paintKeyError.setStyle(Paint.Style.STROKE); 
    paintKeyError.setStrokeWidth(3); 
 
  } 
 
  @Override 
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    // TODO Auto-generated method stub 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
  } 
 
  @Override 
  protected void onLayout(boolean changed, int left, int top, int right, 
      int bottom) { 
    // TODO Auto-generated method stub 
    super.onLayout(changed, left, top, right, bottom); 
    int perSize = 0; 
    if (cycles == null && (perSize = getWidth() / 6) > 0) { 
 
      cycles = new MyCycle[9]; 
      for (int i = 0; i < 3; i++) { 
        for (int j = 0; j < 3; j++) { 
          MyCycle cycle = new MyCycle(); 
          cycle.setNum(i * 3 + j); 
          cycle.setOx(perSize * (j * 2 + 1)); 
          cycle.setOy(perSize * (i * 2 + 1)); 
          cycle.setR(perSize * 0.5f); 
          cycles[i * 3 + j] = cycle; 
        } 
      } 
    } 
  } 
 
  /** 
   * 繪制所需要繪制的內(nèi)容 
   */ 
  @Override 
  protected void onDraw(Canvas canvas) { 
    // TODO Auto-generated method stub 
    super.onDraw(canvas); 
    for (int i = 0; i < cycles.length; i++) { 
 
      if (!canContinue && !result) { 
        paintOnTouch.setColor(ERROR_COLOR); 
        paintInnerCycle.setColor(ERROR_COLOR); 
        paintLines.setColor(ERROR_COLOR); 
      } else if (cycles[i].isOnTouch()) { 
        paintOnTouch.setColor(OUT_CYCLE_ONTOUCH); 
        paintInnerCycle.setColor(INNER_CYCLE_ONTOUCH); 
        paintLines.setColor(LINE_COLOR); 
      } else { 
        paintNormal.setColor(OUT_CYCLE_NORMAL); 
        paintInnerCycle.setColor(INNER_CYCLE_ONTOUCH); 
        paintLines.setColor(LINE_COLOR); 
      } 
 
      if (cycles[i].isOnTouch()) { 
        canvas.drawCircle(cycles[i].getOx(), cycles[i].getOy(), 
            cycles[i].getR(), paintOnTouch); 
        drawInnerBuleCycle(cycles[i], canvas); 
      } else { 
 
        canvas.drawCircle(cycles[i].getOx(), cycles[i].getOy(), 
            cycles[i].getR(), paintNormal); 
      } 
    } 
    drawLine(canvas); 
  } 
 
  /** 
   * 繪制大圓里的小圓 
   * 
   * @param canvas 
   */ 
  private void drawInnerBuleCycle(MyCycle cycle, Canvas canvas) { 
    canvas.drawCircle(cycle.getOx(), cycle.getOy(), cycle.getR() / 3, 
        paintInnerCycle); 
  } 
 
  private void drawLine(Canvas canvas) { 
    linePath.reset(); 
    if (linedCycles.size() > 0) { 
      for (int i = 0; i < linedCycles.size(); i++) { 
        int index = linedCycles.get(i); 
        if (i == 0) { 
          // 設(shè)置為整條路徑的起點 
          linePath.moveTo(cycles[index].getOx(), cycles[i].getOy()); 
        } else { 
          linePath.lineTo(cycles[i].getOx(), cycles[i].getOy()); 
        } 
      } 
      linePath.lineTo(eventX, eventY); 
      canvas.drawPath(linePath, paintLines); 
    } 
  } 
 
  /** 
   * 根據(jù)手擇時觸摸點的不同,修改對應的狀態(tài)值 
   */ 
  @Override 
  public boolean onTouchEvent(MotionEvent event) { 
 
    if (canContinue) { 
 
      switch (event.getAction()) { 
 
      case MotionEvent.ACTION_DOWN: 
      case MotionEvent.ACTION_MOVE: 
        eventX = (int) event.getX(); 
        eventY = (int) event.getY(); 
        for (int i = 0; i < cycles.length; i++) { 
          if (cycles[i].isPointIn(eventX, eventY)) { 
            cycles[i].setOnTouch(true); 
 
            if (!linedCycles.contains(cycles[i].getNum())) { 
              linedCycles.add(cycles[i].getNum()); 
            } 
          } 
        } 
        break; 
      case MotionEvent.ACTION_UP: 
        canContinue = false; 
        StringBuffer sb = new StringBuffer(); 
        for (int i = 0; i < linedCycles.size(); i++) { 
          sb.append(linedCycles.get(i)); 
        } 
        result = key.equals(sb.toString()); 
        if (onGestureFinishListener != null) { 
          onGestureFinishListener.OnGestureFinish(result); 
        } 
        timer = new Timer(); 
        timer.schedule(new TimerTask() { 
 
          @Override 
          public void run() { 
            // 回到初始狀態(tài) 
            eventX = eventY = 0; 
            for (int i = 0; i < cycles.length; i++) { 
              cycles[i].setOnTouch(false); 
            } 
            linedCycles.clear(); 
            linePath.reset(); 
            canContinue = true; 
            postInvalidate(); 
          } 
        }, 1000); 
        break; 
      } 
    } 
    invalidate(); 
    return true; 
  } 
} 

自定義圓類:

package com.example.gesturelock; 
 
public class MyCycle { 
  private int ox;     // Բ�ĺ����� 
  private int oy;     // Բ�������� 
  private float r;     // �뾶���� 
  private Integer num;   // ������ֵ 
  private boolean onTouch; // false=δѡ�� 
  public int getOx() { 
    return ox; 
  } 
  public void setOx(int ox) { 
    this.ox = ox; 
  } 
  public int getOy() { 
    return oy; 
  } 
  public void setOy(int oy) { 
    this.oy = oy; 
  } 
  public float getR() { 
    return r; 
  } 
  public void setR(float r) { 
    this.r = r; 
  } 
  public Integer getNum() { 
    return num; 
  } 
  public void setNum(Integer num) { 
    this.num = num; 
  } 
  public boolean isOnTouch() { 
    return onTouch; 
  } 
  public void setOnTouch(boolean onTouch) { 
    this.onTouch = onTouch; 
  } 
  public boolean isPointIn(int x, int y) { 
    double distance = Math.sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy)); 
    return distance < r; 
  } 
} 

思路:

     1.自定義一個 View和MyCircle類,將九個MyCircle類的實例繪制到View中.

     2.處理onTouch事件,根據(jù)不同的事件修改MyCircle實例的狀態(tài),并調(diào)用更新invaildate更新View

     3.重寫onDraw()方法,根據(jù)不同的狀態(tài)去重新繪制整個View

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Flutter?DateTime獲取本月的開始時間與結(jié)束時間方法

    Flutter?DateTime獲取本月的開始時間與結(jié)束時間方法

    這篇文章主要為大家介紹了Flutter?DateTime獲取本月的開始時間與結(jié)束時間方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2023-05-05
  • Android EditText禁止輸入空格和特殊字符

    Android EditText禁止輸入空格和特殊字符

    本文主要介紹了Android EditText禁止輸入空格和特殊字符的實現(xiàn)代碼。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • Android 九宮格的實現(xiàn)方法

    Android 九宮格的實現(xiàn)方法

    今天在瀏覽網(wǎng)頁的時候看到了一篇有關(guān)九宮格實現(xiàn)的博文,感覺挺有意思。所以自己模仿做了一個,先貼出代碼如下:
    2013-05-05
  • Andriod 讀取網(wǎng)絡(luò)圖片實例代碼解析

    Andriod 讀取網(wǎng)絡(luò)圖片實例代碼解析

    Android手機上,我們經(jīng)常用imageview顯示圖片,通過本文學習獲取網(wǎng)絡(luò)圖片并顯示在imageview中,對android讀取網(wǎng)絡(luò)圖片相關(guān)知識感興趣的朋友一起學習吧
    2016-02-02
  • 利用Jetpack?Compose實現(xiàn)繪制五角星效果

    利用Jetpack?Compose實現(xiàn)繪制五角星效果

    這篇文章主要為大家介紹了Jetpack?Compose如何使用自定義操作符實現(xiàn)繪制五角星效果,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-04-04
  • Android 利用反射+try catch實現(xiàn)sdk按需引入依賴庫的方法

    Android 利用反射+try catch實現(xiàn)sdk按需引入依賴庫的方法

    這篇文章主要介紹了Android 利用反射+try catch來實現(xiàn)sdk按需引入依賴庫,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Android仿Win8界面開發(fā)

    Android仿Win8界面開發(fā)

    這篇文章主要介紹了Android仿Win8界面開發(fā)的實例代碼,將要模仿的Win8界面的一個個設(shè)計,分割成一個一個的方塊,感興趣的小伙伴們可以參考一下
    2015-12-12
  • Android使用AnimationDrawable實現(xiàn)閃爍紅光動畫效果(案例詳解)

    Android使用AnimationDrawable實現(xiàn)閃爍紅光動畫效果(案例詳解)

    這篇文章主要介紹了Android使用AnimationDrawable實現(xiàn)閃爍紅光動畫效果,實現(xiàn)閃爍紅光效果可以使用Android中的Animation和Drawable資源,本文結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • Android程序開發(fā)之防止密碼輸入錯誤 密碼明文顯示功能

    Android程序開發(fā)之防止密碼輸入錯誤 密碼明文顯示功能

    在使用App的時候,首次登錄都需要用戶輸入密碼的,有些朋友為了安全起見密碼設(shè)置的比較長,導致很多次密碼都輸入錯誤,嚴重影響了用戶體驗效果,下面通過本文給大家介紹Android程序開發(fā)之防止密碼輸入錯誤 密碼明文顯示功能,需要的朋友參考下
    2016-02-02
  • Android簡單獲取經(jīng)緯度的方法

    Android簡單獲取經(jīng)緯度的方法

    這篇文章主要介紹了Android簡單獲取經(jīng)緯度的方法,涉及Android位置運算的相關(guān)操作技巧,需要的朋友可以參考下
    2016-08-08

最新評論