废话不多说,直接贴代码,自己写的,转载请注明出处,
/**开发者:易魏 * 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); } }