zoukankan      html  css  js  c++  java
  • 手势解锁自定义View

      1 package com.rxx.view;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 import java.util.Timer;
      6 import java.util.TimerTask;
      7 import android.content.Context;
      8 import android.graphics.Canvas;
      9 import android.graphics.Color;
     10 import android.graphics.Paint;
     11 import android.graphics.Path;
     12 import android.util.AttributeSet;
     13 import android.view.MotionEvent;
     14 import android.view.View;
     15 
     16 /**
     17  * 自定义锁屏View
     18  */
     19 public class GestureLockView extends View {
     20     /** 解锁密码key */
     21     private String key = "";
     22     private OnGestureFinishListener onGestureFinishListener;
     23 
     24     /** 解锁圆点数组 */
     25     private LockCircle[] cycles;
     26     /** 存储触碰圆的序列 */
     27     private List<Integer> linedCycles = new ArrayList<Integer>();
     28 
     29     // 画笔
     30     /** 空心外圆 */
     31     private Paint paintNormal;
     32     /** 点击后内部圆 */
     33     private Paint paintInnerCycle;
     34     /** 画路径 */
     35     private Paint paintLines;
     36     private Path linePath = new Path();
     37 
     38     /** 当前手指X,Y位置 */
     39     private int eventX, eventY;
     40 
     41     /** 能否操控界面绘画 */
     42     private boolean canContinue = true;
     43     /** 验证结果 */
     44     private boolean result;
     45     private Timer timer;
     46 
     47     /** 未选中颜色 */
     48     private final int NORMAL_COLOR = Color.parseColor("#959BB4");
     49     /** 错误颜色 */
     50     private final int ERROE_COLOR = Color.parseColor("#FF2525"); // 正常外圆颜色
     51     /** 选中时颜色 */
     52     private final int TOUCH_COLOR = Color.parseColor("#409DE5"); // 选中内圆颜色
     53 
     54     // =================================start=构造方法========================
     55     public GestureLockView(Context context, AttributeSet attrs, int defStyle) {
     56         super(context, attrs, defStyle);
     57         init();
     58     }
     59 
     60     public GestureLockView(Context context, AttributeSet attrs) {
     61         this(context, attrs, 0);
     62     }
     63 
     64     public GestureLockView(Context context) {
     65         this(context, null);
     66     }
     67 
     68     // ===============================end=构造方法========================
     69 
     70     /** 初始化 */
     71     public void init() {
     72         paintNormal = new Paint();
     73         paintNormal.setAntiAlias(true);
     74         paintNormal.setStrokeWidth(5);
     75         paintNormal.setStyle(Paint.Style.STROKE);
     76 
     77         paintInnerCycle = new Paint();
     78         paintInnerCycle.setAntiAlias(true);
     79         paintInnerCycle.setStyle(Paint.Style.FILL);
     80 
     81         paintLines = new Paint();
     82         paintLines.setAntiAlias(true);
     83         paintLines.setStyle(Paint.Style.STROKE);
     84         paintLines.setStrokeWidth(10);
     85 
     86     }
     87 
     88     @Override
     89     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     90         int specMode = MeasureSpec.getMode(widthMeasureSpec);
     91         int spceSize = MeasureSpec.getSize(widthMeasureSpec);
     92         heightMeasureSpec = MeasureSpec.makeMeasureSpec(
     93                 (int) (spceSize * 0.85 + 0.5f), specMode);
     94         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     95     }
     96 
     97     @Override
     98     protected void onLayout(boolean changed, int left, int top, int right,
     99             int bottom) {
    100         super.onLayout(changed, left, top, right, bottom);
    101         int perWidthSize = getWidth() / 7;
    102         int perHeightSize = getHeight() / 6;
    103         /** 初始化圆的参数 */
    104         if (cycles == null && (perWidthSize > 0) && (perHeightSize > 0)) {
    105             cycles = new LockCircle[9];
    106             for (int i = 0; i < 3; i++) {
    107                 for (int j = 0; j < 3; j++) {
    108                     LockCircle lockCircle = new LockCircle();
    109                     lockCircle.setNum(i * 3 + j);
    110                     lockCircle.setOx(perWidthSize * (j * 2 + 1.5f) + 0.5f);
    111                     lockCircle.setOy(perHeightSize * (i * 2 + 1) + 0.5f);
    112                     lockCircle.setR(perWidthSize * 0.6f);
    113                     cycles[i * 3 + j] = lockCircle;
    114                 }
    115             }
    116         }
    117 
    118     }
    119 
    120     public void setKey(String key) {
    121         this.key = key;
    122     }
    123 
    124     public void setOnGestureFinishListener(
    125             OnGestureFinishListener onGestureFinishListener) {
    126         this.onGestureFinishListener = onGestureFinishListener;
    127     }
    128 
    129     /** 手势输入完成后回调接口 */
    130     public interface OnGestureFinishListener {
    131         /** 手势输入完成后回调函数 */
    132         public void OnGestureFinish(boolean success, String key);
    133     }
    134 
    135     /** 监听手势 */
    136     @Override
    137     public boolean onTouchEvent(MotionEvent event) {
    138         if (canContinue) {
    139             switch (event.getAction()) {
    140             case MotionEvent.ACTION_DOWN:
    141             case MotionEvent.ACTION_MOVE:
    142                 eventX = (int) event.getX();
    143                 eventY = (int) event.getY();
    144                 for (int i = 0; i < cycles.length; i++) {
    145                     if (cycles[i].isPointIn(eventX, eventY)) {
    146                         cycles[i].setOnTouch(true);
    147                         if (!linedCycles.contains(cycles[i].getNum())) {
    148                             linedCycles.add(cycles[i].getNum());
    149                         }
    150                     }
    151                 }
    152                 break;
    153             case MotionEvent.ACTION_UP:
    154                 // 手指离开暂停触碰
    155                 canContinue = false;
    156                 StringBuffer stringBuffer = new StringBuffer();
    157                 for (int i = 0; i < linedCycles.size(); i++) {
    158                     stringBuffer.append(linedCycles.get(i));
    159                 }
    160                 result = key.equals(stringBuffer.toString());
    161                 if (onGestureFinishListener != null && linedCycles.size() > 0) {
    162                     onGestureFinishListener.OnGestureFinish(result,
    163                             stringBuffer.toString());
    164                 }
    165                 timer = new Timer();
    166                 timer.schedule(new TimerTask() {
    167                     @Override
    168                     public void run() {
    169                         eventX = eventY = 0;
    170                         for (int i = 0; i < 9; i++) {
    171                             cycles[i].setOnTouch(false);
    172                         }
    173                         linedCycles.clear();
    174                         linePath.reset();
    175                         canContinue = true;
    176                         postInvalidate();// 在非ui线程刷新界面
    177                     }
    178                 }, 1000);
    179                 break;
    180             }
    181             invalidate();
    182         }
    183         return true;
    184     }
    185 
    186     @Override
    187     protected void onDraw(Canvas canvas) {
    188         super.onDraw(canvas);
    189         int cycleSize = cycles.length;
    190         for (int i = 0; i < cycleSize; i++) {
    191             // 画完并且错误
    192             if (!canContinue && !result) {
    193                 if (cycles[i].isOnTouch()) {
    194                     drawInnerCycle(cycles[i], canvas, ERROE_COLOR);
    195                     drawOutsideCycle(cycles[i], canvas, ERROE_COLOR);
    196                 } else
    197                     drawOutsideCycle(cycles[i], canvas, NORMAL_COLOR);
    198             }
    199             // 绘画中
    200             else {
    201                 if (cycles[i].isOnTouch()) {
    202                     drawInnerCycle(cycles[i], canvas, TOUCH_COLOR);
    203                     drawOutsideCycle(cycles[i], canvas, TOUCH_COLOR);
    204                 } else
    205                     drawOutsideCycle(cycles[i], canvas, NORMAL_COLOR);
    206             }
    207         }
    208 
    209         if (!canContinue && !result) {
    210             drawLine(canvas, ERROE_COLOR);
    211         } else {
    212             drawLine(canvas, TOUCH_COLOR);
    213         }
    214 
    215     }
    216 
    217     /** 画空心圆 */
    218     private void drawOutsideCycle(LockCircle lockCircle, Canvas canvas,
    219             int color) {
    220         paintNormal.setColor(color);
    221         canvas.drawCircle(lockCircle.getOx(), lockCircle.getOy(),
    222                 lockCircle.getR(), paintNormal);
    223     }
    224 
    225     /** 画横线 */
    226     private void drawLine(Canvas canvas, int color) {
    227         // 构建路径
    228         linePath.reset();
    229         if (linedCycles.size() > 0) {
    230             int size = linedCycles.size();
    231             for (int i = 0; i < size; i++) {
    232                 int index = linedCycles.get(i);
    233                 float x = cycles[index].getOx();
    234                 float y = cycles[index].getOy();
    235                 if (i == 0) {
    236                     linePath.moveTo(x, y);
    237                 } else {
    238                     linePath.lineTo(x, y);
    239                 }
    240             }
    241             if (canContinue) {
    242                 linePath.lineTo(eventX, eventY);
    243             } else {
    244                 linePath.lineTo(
    245                         cycles[linedCycles.get(linedCycles.size() - 1)].getOx(),
    246                         cycles[linedCycles.get(linedCycles.size() - 1)].getOy());
    247             }
    248             paintLines.setColor(color);
    249             canvas.drawPath(linePath, paintLines);
    250         }
    251     }
    252 
    253     /** 画中心圆圆 */
    254     private void drawInnerCycle(LockCircle myCycle, Canvas canvas, int color) {
    255         paintInnerCycle.setColor(color);
    256         canvas.drawCircle(myCycle.getOx(), myCycle.getOy(),
    257                 myCycle.getR() / 3f, paintInnerCycle);
    258     }
    259 
    260     /**
    261      * 每个圆点类
    262      */
    263     class LockCircle {
    264         /** 圆心横坐标 */
    265         private float ox;
    266         /** 圆心纵坐标 */
    267         private float oy;
    268         /** 半径长度 */
    269         private float r;
    270         /** 代表数值 */
    271         private Integer num;
    272         /** 是否选择:false=未选中 */
    273         private boolean onTouch;
    274 
    275         public float getOx() {
    276             return ox;
    277         }
    278 
    279         public void setOx(float ox) {
    280             this.ox = ox;
    281         }
    282 
    283         public float getOy() {
    284             return oy;
    285         }
    286 
    287         public void setOy(float oy) {
    288             this.oy = oy;
    289         }
    290 
    291         public void setOy(int oy) {
    292             this.oy = oy;
    293         }
    294 
    295         public float getR() {
    296             return r;
    297         }
    298 
    299         public void setR(float r) {
    300             this.r = r;
    301         }
    302 
    303         public Integer getNum() {
    304             return num;
    305         }
    306 
    307         public void setNum(Integer num) {
    308             this.num = num;
    309         }
    310 
    311         public boolean isOnTouch() {
    312             return onTouch;
    313         }
    314 
    315         public void setOnTouch(boolean onTouch) {
    316             this.onTouch = onTouch;
    317         }
    318 
    319         /** 判读传入位置是否在圆心内部 */
    320         public boolean isPointIn(int x, int y) {
    321             double distance = Math.sqrt((x - ox) * (x - ox) + (y - oy)
    322                     * (y - oy));
    323             return distance < r;
    324         }
    325     }
    326 }
     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="fill_parent"
     3     android:layout_height="fill_parent"
     4     android:background="#232736"
     5     android:gravity="center"
     6     android:orientation="vertical" >
     7 
     8     <!-- 小头像 -->
     9     <ImageView
    10         android:layout_width="70dp"
    11         android:layout_height="70dp"
    12         android:src="@drawable/tempfenlei" />
    13 
    14     <TextView
    15         android:id="@+id/textview"
    16         android:layout_width="wrap_content"
    17         android:layout_height="wrap_content"
    18         android:layout_marginTop="10dp"
    19         android:text=""
    20         android:textColor="#FF2525"
    21         android:textSize="16sp"
    22         android:visibility="invisible" />
    23 
    24     <com.rxx.view.GestureLockView
    25         android:id="@+id/gestureLockView"
    26         android:layout_width="wrap_content"
    27         android:layout_height="wrap_content" />
    28 
    29     <LinearLayout
    30         android:layout_width="fill_parent"
    31         android:layout_height="wrap_content"
    32         android:orientation="horizontal"
    33         android:padding="10dp" >
    34 
    35         <TextView
    36             android:layout_width="fill_parent"
    37             android:layout_height="wrap_content"
    38             android:layout_weight="1"
    39             android:gravity="center"
    40             android:text="管理手势密码"
    41             android:textColor="#585C6E"
    42             android:textSize="16sp" />
    43 
    44         <TextView
    45             android:layout_width="fill_parent"
    46             android:layout_height="wrap_content"
    47             android:layout_weight="1"
    48             android:gravity="center"
    49             android:text="登陆其他账号"
    50             android:textColor="#585C6E"
    51             android:textSize="16sp" />
    52     </LinearLayout>
    53 
    54 </LinearLayout>
     1 package com.rxx.gesturelockdemo;
     2 
     3 import android.app.Activity;
     4 import android.graphics.Color;
     5 import android.os.Bundle;
     6 import android.view.View;
     7 import android.view.animation.Animation;
     8 import android.view.animation.TranslateAnimation;
     9 import android.widget.TextView;
    10 
    11 import com.rxx.view.GestureLockView;
    12 import com.rxx.view.GestureLockView.OnGestureFinishListener;
    13 
    14 public class MainActivity extends Activity {
    15 
    16     private GestureLockView gestureLockView;
    17     private TextView textview;
    18     private Animation animation;
    19 
    20     @Override
    21     protected void onCreate(Bundle savedInstanceState) {
    22         super.onCreate(savedInstanceState);
    23         setContentView(R.layout.activity_main);
    24         init();
    25     }
    26 
    27     /** 初始化 */
    28     public void init() {
    29         gestureLockView = (GestureLockView) findViewById(R.id.gestureLockView);
    30         textview = (TextView) findViewById(R.id.textview);
    31         animation = new TranslateAnimation(-20, 20, 0, 0);
    32         animation.setDuration(50);
    33         animation.setRepeatCount(2);
    34         animation.setRepeatMode(Animation.REVERSE);
    35         // 设置密码
    36         gestureLockView.setKey("1");
    37         // 手势完成后回调
    38         gestureLockView
    39                 .setOnGestureFinishListener(new OnGestureFinishListener() {
    40                     @Override
    41                     public void OnGestureFinish(boolean success, String key) {
    42                         if (success) {
    43                             textview.setTextColor(Color.parseColor("#FFFFFF"));
    44                             textview.setVisibility(View.VISIBLE);
    45                             textview.setText("密码正确!");
    46                             textview.startAnimation(animation);
    47                         } else {
    48                             textview.setTextColor(Color.parseColor("#FF2525"));
    49                             textview.setVisibility(View.VISIBLE);
    50                             textview.setText("密码错误!");
    51                             textview.startAnimation(animation);
    52                         }
    53                     }
    54                 });
    55     }
    56 }
  • 相关阅读:
    Delphi中 弹出框的用法
    VC++代码上传到VSS上 注意事项
    VC++ 屏蔽掉警告
    IIS LocalDB 登录失败
    SVN版本回滚实战
    Git常用命令图解
    C# 百度API地址坐标互相转换
    Quartz.NET浅谈一 : 简单Job使用(定时发送QQ邮件)
    发布自己的类库包到Nuget
    C# 常用日期取得
  • 原文地址:https://www.cnblogs.com/androidsj/p/4290157.html
Copyright © 2011-2022 走看看