废话不多说,直接贴代码,自己写的,转载请注明出处,
/**开发者:易魏 * Created by Administrator on 2018/2/27. */ public class UnLockView extends View {private static final String TAG = "UnLockView"; private int Number = 4; private int tempX = 0; private int tempY = 0; private int minSize = 4; private int UnTouchColor = 0xffffffff; private int TouchColor = 0xffffffff; private int lineColor = 0xffffffff; private Paint unTouchPaint; private Paint touchPaint; private Paint linePaint; private int mR = 0; private int pointAchor; private ArrayList<String> checks = new ArrayList<>(); private Point nowPoint = new Point(); private boolean isAllowTouchAgain = false; private boolean BeforeTouch = false; private PasswordResult passwordResult = null; private ArrayList<Point> points = new ArrayList<>(); private ArrayList<Point> isTouchPoints = new ArrayList<>(); private HashMap<Integer, Point> touchMap = new HashMap<>(); private HashMap<Integer, Point> pointMap = new HashMap<>(); public UnLockView(Context context) {super(context); }public UnLockView(Context context, AttributeSet attrs) {super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.UnLockView); Number = typedArray.getColor(R.styleable.UnLockView_number, 0xffffffff); UnTouchColor = typedArray.getColor(R.styleable.UnLockView_unCheckColor, 0xffffffff); TouchColor = typedArray.getColor(R.styleable.UnLockView_checkColor, 0xffffffff); touchPaint = new Paint(); unTouchPaint = new Paint(); linePaint = new Paint(); unTouchPaint.setAntiAlias(true); touchPaint.setAntiAlias(true); linePaint.setAntiAlias(true); touchPaint.setColor(TouchColor); unTouchPaint.setColor(UnTouchColor); linePaint.setColor(lineColor); touchPaint.setStyle(Paint.Style.FILL); unTouchPaint.setStyle(Paint.Style.STROKE); unTouchPaint.setStrokeWidth(10); linePaint.setStyle(Paint.Style.STROKE); }public UnLockView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr); }@Override protected void onDraw(Canvas canvas) {super.onDraw(canvas); //这里防止平板或者横竖屏 if (canvas.getHeight() > canvas.getWidth()) {mR = canvas.getWidth() / ((Number + 1) * 3); pointAchor = canvas.getWidth() / (Number + 1); } else {mR = canvas.getHeight() / ((Number + 1) * 3); pointAchor = canvas.getHeight() / (Number + 1); }linePaint.setStrokeWidth(mR / 3); if (tempX != Number || tempY != Number) {for (int i = 0; i < Number; i++) {for (int j = 0; j < Number; j++) {Point point = new Point(); point.setX(j); point.setY(i); point.setNumber(j + i * Number); Log.i(TAG, "onDraw: 点" + (j + i * Number)); points.add(point); pointMap.put(point.getNumber(), point); }}tempX = Number; tempY = Number; }for (int i = 0; i < points.size(); i++) {canvas.drawCircle(getPointX(points.get(i).getX()), getPointY(points.get(i).getY()), mR, unTouchPaint); }for (int i = 0; i < isTouchPoints.size(); i++) {canvas.drawCircle(getPointX(isTouchPoints.get(i).getX()), getPointY(isTouchPoints.get(i).getY()), mR, touchPaint); } for (int i = 0; i < isTouchPoints.size(); i++) {if (i == isTouchPoints.size() - 1) {canvas.drawLine(getPointX(isTouchPoints.get(i).getX()), getPointY(isTouchPoints.get(i).getY()), nowPoint.getX(), nowPoint.getY(), linePaint); } else {canvas.drawLine(getPointX(isTouchPoints.get(i).getX()), getPointY(isTouchPoints.get(i).getY()), getPointX(isTouchPoints.get(i + 1).getX()), getPointY(isTouchPoints.get(i + 1).getY()), linePaint); }}for (int i = 0; i < isTouchPoints.size(); i++) {touchMap.put(isTouchPoints.get(i).getNumber(), isTouchPoints.get(i)); }}@Override public boolean onTouchEvent(MotionEvent event) {if (!isAllowTouchAgain & BeforeTouch) {return true; }BeforeTouch = false; nowPoint.setX((int) event.getX()); nowPoint.setY((int) event.getY()); int now = pointContainNow(event.getX(), event.getY()); if (now != -1) {if (!checks.contains(String.valueOf(now + 1))) {if (isTouchPoints.size() >= 1) {setPointToPoint(isTouchPoints.get(isTouchPoints.size() - 1), points.get(now)); }checks.add(String.valueOf(now + 1)); isTouchPoints.add(points.get(now)); }}switch (event.getAction()) {case MotionEvent.ACTION_UP:BeforeTouch = true; if (isTouchPoints.size() < minSize) {reSet(); Toast.makeText(getContext(), "您的密码小于" + minSize + "个点,请重新设置。", Toast.LENGTH_SHORT).show(); } else {nowPoint.setX(getPointX(isTouchPoints.get(isTouchPoints.size() - 1).getX())); nowPoint.setY(getPointY(isTouchPoints.get(isTouchPoints.size() - 1).getY())); }if (passwordResult != null) {passwordResult.result(checks); }invalidate(); break; }invalidate(); return true; }/** * 判断当前触摸点是否在圆之内。 * * @param x * @param y * @return */ private int pointContainNow(float x, float y) {for (int i = 0; i < points.size(); i++) {if ((getPointX(points.get(i).getX()) + mR / 2) > x & (getPointX(points.get(i).getX()) - mR / 2) < x & (getPointY(points.get(i).getY()) + mR / 2) > y & (getPointY(points.get(i).getY()) - mR / 2) < y) {return i; }}return -1; }private Point getPoint(int number) {return pointMap.get(number); }private void setPointToPoint(Point from, Point to) {int lastPointNum = from.getNumber(); int lastPointX = from.getX(); int lastPointY = from.getY(); int newPointX = to.getX(); int newPointY = to.getY(); int newPointNum = to.getNumber(); if (lastPointNum != newPointNum) {if (lastPointX == newPointX) { int small = getSmall(lastPointNum, newPointNum); int chaju = Math.abs(lastPointY - newPointY); for (int i = 1; i < chaju; i++) {if (touchMap.get(small + (Number * i)) == null) {checks.add(String.valueOf(small + (Number * i) + 1)); isTouchPoints.add(pointMap.get(small + (Number * i))); }}} else if (lastPointY == newPointY) { int small = getSmall(lastPointNum, newPointNum); int chaju = Math.abs(lastPointX - newPointX); for (int i = 1; i < chaju; i++) { if (touchMap.get(small + i) == null) {checks.add(String.valueOf(small + i + 1)); isTouchPoints.add(pointMap.get(small + i)); }}} else if (Math.abs((lastPointX - newPointX)) == Math.abs((lastPointY - newPointY))) {int small = getSmall(lastPointNum, newPointNum); int chajuY = Math.abs(lastPointY - newPointY); for (int j = 1; j < chajuY; j++) {if ((newPointY > lastPointY & newPointX > lastPointX) || (newPointY < lastPointY & newPointX < lastPointX)) { if (touchMap.get(j + small + (Number * j)) == null) {checks.add(String.valueOf(j + small + (Number * j) + 1)); isTouchPoints.add(pointMap.get(j + small + (Number * j))); }} else if ((newPointY > lastPointY & newPointX < lastPointX) || (newPointY < lastPointY & newPointX > lastPointX)) {if (touchMap.get(small + (Number * j) - j) == null) { checks.add(String.valueOf(small + (Number * j) - j + 1)); isTouchPoints.add(pointMap.get(small + (Number * j) - j)); }}}if (lastPointNum > newPointNum) {}}}}private int getSmall(int arg1, int arg2) {if (arg1 > arg2) {return arg2; } else {return arg1; }}private int getPointX(int Xnumber) {return pointAchor * (Xnumber + 1); }private int getPointY(int Ynumber) {return pointAchor * (Ynumber + 1); }public void reSet() {isTouchPoints.clear(); checks.clear(); BeforeTouch = false; touchMap.clear(); invalidate(); }public int getTouchColor() {return TouchColor; }public void setTouchColor(int touchColor) {TouchColor = touchColor; invalidate(); }public Paint getTouchPaint() {return touchPaint; }public void setTouchPaint(Paint touchPaint) {this.touchPaint = touchPaint; invalidate(); }public int getUnTouchColor() {return UnTouchColor; }public void setUnTouchColor(int unTouchColor) {UnTouchColor = unTouchColor; invalidate(); }public Paint getUnTouchPaint() {return unTouchPaint; }public void setUnTouchPaint(Paint unTouchPaint) {this.unTouchPaint = unTouchPaint; invalidate(); }public int getLineColor() {return lineColor; }public void setLineColor(int lineColor) {this.lineColor = lineColor; invalidate(); }public int getNumber() {return Number; }public void setNumber(int number) {Number = Number; Number = Number; Number = number; }public boolean isAllowTouchAgain() {return isAllowTouchAgain; }public void setAllowTouchAgain(boolean allowTouchAgain) {isAllowTouchAgain = allowTouchAgain; }public PasswordResult getPasswordResult() {return passwordResult; }public void setPasswordResult(PasswordResult passwordResult) {this.passwordResult = passwordResult; }class Point {private int X; private int Y; private int number; public int getX() {return X; }public void setX(int x) {X = x; }public int getY() {return Y; }public void setY(int y) {Y = y; }public int getNumber() {return number; }public void setNumber(int number) {this.number = number; }}interface PasswordResult {void result(ArrayList<String> result); } }