2525/**
2626 * PatternLockView support two layout mode:
2727 * PatternLockView 支持两种布局模式:
28- *
28+ * <p>
2929 * 1. SpacingPadding mode:
30- * If lock_spacing is given, PatternLockView use lock_nodeSize, lock_spacing and lock_padding to layout the view.
31- * Detail Rules:
32- * a. Use exactly lock_nodeSize, spacing and lock_padding to layout. If insufficient space, try b.
33- * b. Keep lock_nodeSize, reduce lock_spacing and lock_padding with equal proportion. If insufficient space, try c.
34- * c. Keep lock_spacing and lock_padding, reduce lock_nodeSize. If insufficient space, try d.
35- * d. Apply Identical-Area mode.
36- *
37- * 如果设置了lock_spacing时,PatternLockView会使用lock_nodeSize, lock_spacing, lock_padding去布局
38- * 具体布局规则如下:
39- * a.精确按照lock_nodeSize, lock_spacing, lock_padding去布局进行布局,如果空间不足采用b规则;
40- * b.保持lock_nodeSize大小不变,按比例缩小lock_spacing与lock_padding去布局,如果spacing与padding空间小于0,采用c规则;
41- * c.保持lock_spacing与lock_padding,缩小lock_nodeSize,如果lock_nodeSize小于0,采用d规则;
42- * d.采用Identical-Area mode;
43- *
30+ * If lock_spacing is given, PatternLockView use lock_nodeSize, lock_spacing and lock_padding to layout the view.
31+ * Detail Rules:
32+ * a. Use exactly lock_nodeSize, spacing and lock_padding to layout. If insufficient space, try b.
33+ * b. Keep lock_nodeSize, reduce lock_spacing and lock_padding with equal proportion. If insufficient space, try c.
34+ * c. Keep lock_spacing and lock_padding, reduce lock_nodeSize. If insufficient space, try d.
35+ * d. Apply Identical-Area mode.
36+ * <p>
37+ * 如果设置了lock_spacing时,PatternLockView会使用lock_nodeSize, lock_spacing, lock_padding去布局
38+ * 具体布局规则如下:
39+ * a.精确按照lock_nodeSize, lock_spacing, lock_padding去布局进行布局,如果空间不足采用b规则;
40+ * b.保持lock_nodeSize大小不变,按比例缩小lock_spacing与lock_padding去布局,如果spacing与padding空间小于0,采用c规则;
41+ * c.保持lock_spacing与lock_padding,缩小lock_nodeSize,如果lock_nodeSize小于0,采用d规则;
42+ * d.采用Identical-Area mode;
43+ * <p>
4444 * 2. Identical-Area mode:
45- * If lock_spacing is NOT given, PatternLockView only use lock_nodeSize to layout the view(lock_spacing and lock_padding are ignored).
46- * It divides the whole area into n * n identical cells, and layout the node in the center of each cell
47- *
48- * 如果未设置lock_spacing时,PatternLockView将只使用lock_nodeSize,而无视lock_spacing与lock_padding去布局。
49- * 其会将空间等分为n * n个空间,并将节点居中放置
50- *
51-
45+ * If lock_spacing is NOT given, PatternLockView only use lock_nodeSize to layout the view(lock_spacing and lock_padding are ignored).
46+ * It divides the whole area into n * n identical cells, and layout the node in the center of each cell
47+ * <p>
48+ * 如果未设置lock_spacing时,PatternLockView将只使用lock_nodeSize,而无视lock_spacing与lock_padding去布局。
49+ * 其会将空间等分为n * n个空间,并将节点居中放置
5250 *
5351 * @author xyxyLiu
5452 * @version 1.0
@@ -88,9 +86,12 @@ public class PatternLockView extends ViewGroup {
8886
8987 private float mNodeAreaExpand ;
9088 private int mNodeOnAnim ;
91- private int mLineColor ;
9289 private float mLineWidth ;
9390
91+ private int mLineColor ;
92+ private int mLineCorrectColor ;
93+ private int mLineErrorColor ;
94+
9495 private float mNodeSize ;
9596 // only used in Identical-Area mode, whether to keep each square
9697 private boolean mIsSquareArea = true ;
@@ -151,6 +152,7 @@ public void setTouchEnabled(boolean isEnabled) {
151152
152153 /**
153154 * time delayed of the lock view resetting after user finish input password
155+ *
154156 * @param timeout timeout
155157 */
156158 public void setFinishTimeout (long timeout ) {
@@ -161,16 +163,18 @@ public void setFinishTimeout(long timeout) {
161163
162164 /**
163165 * whether user can start a new password input in the period of FinishTimeout
164- * @see #setFinishTimeout(long)
166+ *
165167 * @param isInterruptable if true, the lock view will be reset when user touch a new node.
166168 * if false, the lock view will be reset only when the finish timeout expires
169+ * @see #setFinishTimeout(long)
167170 */
168171 public void setFinishInterruptable (boolean isInterruptable ) {
169172 mIsFinishInterruptable = isInterruptable ;
170173 }
171174
172175 /**
173176 * whether the nodes in the path of two selected nodes will be automatic linked
177+ *
174178 * @param isEnabled enabled
175179 */
176180 public void setAutoLinkEnabled (boolean isEnabled ) {
@@ -214,6 +218,8 @@ private void initFromAttributes(Context context, AttributeSet attrs, int defStyl
214218 mNodeAreaExpand = a .getDimension (R .styleable .PatternLockView_lock_nodeTouchExpand , 0 );
215219 mNodeOnAnim = a .getResourceId (R .styleable .PatternLockView_lock_nodeOnAnim , 0 );
216220 mLineColor = a .getColor (R .styleable .PatternLockView_lock_lineColor , Color .argb (0xb2 , 0xff , 0xff , 0xff ));
221+ mLineCorrectColor = a .getColor (R .styleable .PatternLockView_lock_lineCorrectColor , mLineColor );
222+ mLineErrorColor = a .getColor (R .styleable .PatternLockView_lock_lineErrorColor , mLineColor );
217223 mLineWidth = a .getDimension (R .styleable .PatternLockView_lock_lineWidth , (int ) TypedValue .applyDimension (
218224 TypedValue .COMPLEX_UNIT_DIP , 5 , getResources ().getDisplayMetrics ()));
219225 mPadding = a .getDimension (R .styleable .PatternLockView_lock_padding , 0 );
@@ -455,14 +461,7 @@ public boolean onTouchEvent(MotionEvent event) {
455461
456462 if (mCallBack != null ) {
457463 int result = mCallBack .onFinish (new Password (mNodeList ));
458- switch (result ) {
459- case CODE_PASSWORD_CORRECT :
460- setFinishState (NodeView .STATE_CORRECT );
461- break ;
462- case CODE_PASSWORD_ERROR :
463- setFinishState (NodeView .STATE_ERROR );
464- break ;
465- }
464+ setFinishState (result );
466465 }
467466
468467 currentNode = null ;
@@ -475,17 +474,34 @@ public boolean onTouchEvent(MotionEvent event) {
475474 return true ;
476475 }
477476
478- private void setupNodes (int size ){
477+ private void setupNodes (int size ) {
479478 removeAllViews ();
480479 for (int n = 0 ; n < size * size ; n ++) {
481480 NodeView node = new NodeView (getContext (), n );
482481 addView (node );
483482 }
484483 }
485484
486- private void setFinishState (int state ) {
487- for (NodeView nodeView : mNodeList ) {
488- nodeView .setState (state );
485+ private void setFinishState (int result ) {
486+ int nodeState = -1 ;
487+ int lineColor = mLineColor ;
488+
489+ if (result == CODE_PASSWORD_CORRECT ) {
490+ nodeState = NodeView .STATE_CORRECT ;
491+ lineColor = mLineCorrectColor ;
492+ } else if (result == CODE_PASSWORD_ERROR ) {
493+ nodeState = NodeView .STATE_ERROR ;
494+ lineColor = mLineErrorColor ;
495+ }
496+
497+ if (nodeState >= 0 ) {
498+ for (NodeView nodeView : mNodeList ) {
499+ nodeView .setState (nodeState );
500+ }
501+ }
502+
503+ if (lineColor != mLineColor ) {
504+ mPaint .setColor (lineColor );
489505 }
490506 }
491507
@@ -499,6 +515,7 @@ private void addNodeToList(NodeView nodeView) {
499515 /**
500516 * auto link the nodes between first and second
501517 * 检测两个节点间的中间检点是否未连接,否则按顺序连接。
518+ *
502519 * @param first
503520 * @param second
504521 */
@@ -594,10 +611,10 @@ private boolean isMeasureModeExactly(int measureMode) {
594611 public interface CallBack {
595612 /**
596613 * @param password password
597- * @see com.reginald.patternlockview.PatternLockView.Password
598614 * @return return value 解锁结果返回值:
599615 * {@link #CODE_PASSWORD_CORRECT},
600616 * {@link #CODE_PASSWORD_ERROR},
617+ * @see com.reginald.patternlockview.PatternLockView.Password
601618 */
602619 int onFinish (Password password );
603620 }
@@ -701,11 +718,11 @@ public String toString() {
701718 }
702719 }
703720
704- public static class Password {
721+ public static class Password {
705722 public final List <Integer > list ;
706723 public final String string ;
707724
708- public Password (List <NodeView > nodeViewList ){
725+ public Password (List <NodeView > nodeViewList ) {
709726 // build password id list
710727 list = new ArrayList <>();
711728 for (NodeView node : nodeViewList ) {
0 commit comments