Android 사용자 정의 UI 제스처 암호 개선 버 전
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"
tools:context=".MainActivity" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text=" "
android:id="@+id/text"
/>
<com.example.lockpatterview.LockPatterView
android:id="@+id/lock"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp" />
</LinearLayout>
MainActivity
package com.example.lockpatterview;
import com.example.lockpatterview.LockPatterView.OnPatterChangeLister;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;
public class MainActivity extends Activity implements OnPatterChangeLister {
LockPatterView lock;
TextView text;
String p = "14789";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
lock = (LockPatterView) findViewById(R.id.lock);
lock.SetOnPatterChangeLister(this);
}
@Override
public void onPatterChange(String passwordStr) {
if (!TextUtils.isEmpty(passwordStr)) {
if (passwordStr.equals(p)) {
text.setText(passwordStr);
} else {
text.setText(" ");
lock.errorPoint();
}
}else {
Toast.makeText(MainActivity.this, " 5 ", 0).show();
}
}
@Override
public void onPatterStart(boolean isStart) {
if (isStart) {
text.setText(" ");
}
}
}
LockPatterView
package com.example.lockpatterview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class LockPatterView extends View {
private static final int POINT_SIZE = 5;
private Point[][] points = new Point[3][3];
private Matrix matrix = new Matrix();
private float width, height, offstartY, moveX, moveY;;
private Bitmap bitmap_pressed, bitmap_normal, bitmap_error, bitmap_line,
bitmap_line_error;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private List<Point> pointList = new ArrayList<LockPatterView.Point>();
private OnPatterChangeLister onPatterChangeLister;
/**
*
*/
public LockPatterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public LockPatterView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LockPatterView(Context context) {
super(context);
}
/*********************************************************
* 9
* movePoint , 9
* isInit 9
* isSelect
* isFinish
*/
private boolean isInit, isSelect, isFinish, movePoint;
@Override
protected void onDraw(Canvas canvas) {
// , ,isInit ---
if (!isInit) {
// 9
initPoints();
}
// 9
points2Canvas(canvas);
if (pointList.size() > 0) {
Point a = pointList.get(0);
//
for (int i = 0; i < pointList.size(); i++) {
Point b = pointList.get(i);
line2Canvas(canvas, a, b);
a = b;
}
//
if (movePoint) {
line2Canvas(canvas, a, new Point(moveX, moveY));
}
}
}
/**
* 9 3 2 9 isInit=
* true --
*/
private void initPoints() {
//
width = getWidth();
height = getHeight();
//
offstartY = (height - width) / 2;
//
bitmap_normal = BitmapFactory.decodeResource(getResources(),
R.drawable.btn_circle_normal);
bitmap_pressed = BitmapFactory.decodeResource(getResources(),
R.drawable.btn_circle_pressed);
bitmap_error = BitmapFactory.decodeResource(getResources(),
R.drawable.btn_circle_selected);
bitmap_line = BitmapFactory.decodeResource(getResources(),
R.drawable.ddd);
bitmap_line_error = BitmapFactory.decodeResource(getResources(),
R.drawable.qqq);
points[0][0] = new Point(width / 4, offstartY + width / 4);
points[0][1] = new Point(width / 2, offstartY + width / 4);
points[0][2] = new Point(width / 4 * 3, offstartY + width / 4);
points[1][0] = new Point(width / 4, offstartY + width / 4 * 2);
points[1][1] = new Point(width / 2, offstartY + width / 4 * 2);
points[1][2] = new Point(width / 4 * 3, offstartY + width / 4 * 2);
points[2][0] = new Point(width / 4, offstartY + width / 4 * 3);
points[2][1] = new Point(width / 2, offstartY + width / 4 * 3);
points[2][2] = new Point(width / 4 * 3, offstartY + width / 4 * 3);
// 1--9
int index = 1;
for (Point[] points : this.points) {
for (Point point : points) {
point.index = index;
index++;
}
}
//
isInit = true;
}
/**
* 9 9 , 3 3 9
*/
private void points2Canvas(Canvas canvas) {
// 9
for (int i = 0; i < points.length; i++) {
// 3
for (int j = 0; j < points[i].length; j++) {
//
Point point = points[i][j];
if (point.state == Point.STATE_PRESSED) {
// (Bitmap bitmap, float left, float top, Paint paint)
canvas.drawBitmap(bitmap_pressed,
point.x - bitmap_normal.getWidth() / 2, point.y
- bitmap_normal.getHeight() / 2, paint);
} else if (point.state == Point.STATE_ERROR) {
canvas.drawBitmap(bitmap_error,
point.x - bitmap_normal.getWidth() / 2, point.y
- bitmap_normal.getHeight() / 2, paint);
} else {
canvas.drawBitmap(bitmap_normal,
point.x - bitmap_normal.getWidth() / 2, point.y
- bitmap_normal.getHeight() / 2, paint);
}
}
}
}
/**
*
*/
public void line2Canvas(Canvas canvas, Point a, Point b) {
// --2
float linelength = (float) Point.distance(a, b);
// 2
float degress = getDegrees(a, b);
// a
canvas.rotate(degress, a.x, a.y);
if (a.state == Point.STATE_PRESSED) {
// xy
matrix.setScale(linelength / bitmap_line.getWidth(), 1);
matrix.postTranslate(a.x - bitmap_line.getWidth() / 2, a.y
- bitmap_line.getHeight() / 2);
canvas.drawBitmap(bitmap_line, matrix, paint);
} else {
matrix.setScale(linelength / bitmap_line.getWidth(), 1);
matrix.postTranslate(a.x - bitmap_line.getWidth() / 2, a.y
- bitmap_line.getHeight() / 2);
canvas.drawBitmap(bitmap_line_error, matrix, paint);
}
//
canvas.rotate(-degress, a.x, a.y);
}
//
public float getDegrees(Point pointA, Point pointB) {
return (float) Math.toDegrees(Math.atan2(pointB.y - pointA.y, pointB.x
- pointA.x));
}
/****************************************************************************
* onTouch
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
moveX = event.getX();
moveY = event.getY();
movePoint = false;
isFinish = false;
Point point = null;
switch (event.getAction()) {
// ,
case MotionEvent.ACTION_DOWN:
if (onPatterChangeLister != null) {
onPatterChangeLister.onPatterStart(true);
}
// ,
resetPoint();
//
point = chechSelectPoint();
if (point != null) {
// 9 , true
isSelect = true;
}
break;
case MotionEvent.ACTION_MOVE:
if (isSelect) {
//
point = chechSelectPoint();
if (point == null) {
movePoint = true;
}
}
break;
case MotionEvent.ACTION_UP:
// ,
isFinish = true;
isSelect = false;
break;
}
// ,
if (!isFinish && isSelect && point != null) {
//
if (crossPoint(point)) {
movePoint = true;
} else {//
point.state = Point.STATE_PRESSED;
pointList.add(point);
}
}
//
if (isFinish) {
//
if (pointList.size() == 1) {
// resetPoint();
errorPoint();
} else if (pointList.size() < POINT_SIZE && pointList.size() > 0) {//
errorPoint();
if (onPatterChangeLister != null) {
onPatterChangeLister.onPatterChange(null);
}
} else {
if (onPatterChangeLister != null) {
String pass = "";
for (int i = 0; i < pointList.size(); i++) {
pass = pass + pointList.get(i).index;
}
if (!TextUtils.isEmpty(pass)) {
onPatterChangeLister.onPatterChange(pass);
}
}
}
}
postInvalidate();
return true;
}
/**
*
*/
public void resetPoint() {
for (int i = 0; i < pointList.size(); i++) {
Point point = pointList.get(i);
point.state = Point.STATE_NORMAL;
}
pointList.clear();
}
/**
*
*/
private Point chechSelectPoint() {
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < points[i].length; j++) {
Point point = points[i][j];
if (Point.with(point.x, point.y, bitmap_normal.getWidth() / 2,
moveX, moveY)) {
return point;
}
}
}
return null;
}
/**
*
*/
private boolean crossPoint(Point point) {
if (pointList.contains(point)) {
return true;
} else {
return false;
}
}
/**
*
*/
public void errorPoint() {
for (Point point : pointList) {
point.state = Point.STATE_ERROR;
}
}
/***********************************************************************
*
*/
public static class Point {
//
public static int STATE_NORMAL = 0;
//
public static int STATE_PRESSED = 1;
//
public static int STATE_ERROR = 2;
public float x, y;
public int index = 0, state = 0;
public Point() {
};
public Point(float x, float y) {
this.x = x;
this.y = y;
}
/**
*
*/
public static double distance(Point a, Point b) {
return Math.sqrt(Math.abs(a.x - b.x) * Math.abs(a.x - b.x)
+ Math.abs(a.y - b.y) * Math.abs(a.y - b.y));
}
/**
*/
public static boolean with(float paintX, float pointY, float r,
float moveX, float moveY) {
return Math.sqrt((paintX - moveX) * (paintX - moveX)
+ (pointY - moveY) * (pointY - moveY)) < r;
}
}
/**
*
*/
public static interface OnPatterChangeLister {
void onPatterChange(String passwordStr);
void onPatterStart(boolean isStart);
}
/**
*
*/
public void SetOnPatterChangeLister(OnPatterChangeLister changeLister) {
if (changeLister != null) {
this.onPatterChangeLister = changeLister;
}
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.