From 699193d0f4aa5d7d799f1de86f1c594e8ef14355 Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sat, 27 Jan 2018 10:36:45 +0800 Subject: [PATCH 1/8] [Fix] If the itemRadius greater than itemWidth or greater than lineWith in line type, the line is not a straight line #7 --- .../src/main/java/com/chaos/view/PinView.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/pinview/src/main/java/com/chaos/view/PinView.java b/pinview/src/main/java/com/chaos/view/PinView.java index 47cd9d8..07d17be 100644 --- a/pinview/src/main/java/com/chaos/view/PinView.java +++ b/pinview/src/main/java/com/chaos/view/PinView.java @@ -128,8 +128,7 @@ public PinView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) } mPinItemSpacing = a.getDimensionPixelOffset(R.styleable.PinView_itemSpacing, res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_spacing)); - mPinItemRadius = a.getDimensionPixelOffset(R.styleable.PinView_itemRadius, - res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_radius)); + mPinItemRadius = a.getDimensionPixelOffset(R.styleable.PinView_itemRadius, 0); mLineWidth = a.getDimensionPixelOffset(R.styleable.PinView_borderWidth, res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_line_width)); mLineColor = a.getColorStateList(R.styleable.PinView_borderColor); @@ -143,6 +142,8 @@ public PinView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) a.recycle(); + checkItemRadius(); + setMaxLength(mPinItemCount); mPaint.setStrokeWidth(mLineWidth); setupAnimator(); @@ -175,6 +176,19 @@ public void onAnimationUpdate(ValueAnimator animation) { }); } + private void checkItemRadius() { + if (mViewType == VIEW_TYPE_LINE) { + int halfOfLineWidth = mLineWidth / 2; + if (mPinItemRadius > halfOfLineWidth) { + throw new RuntimeException("The itemRadius can not be greater than lineWidth when viewType is line"); + } + } + int halfOfItemWidth = (int) (mPinItemWidth / 2); + if (mPinItemRadius > halfOfItemWidth) { + throw new RuntimeException("The itemRadius can not be greater than itemWidth"); + } + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); @@ -678,6 +692,7 @@ public int getBorderWidth() { * @see #getLineWidth() */ public void setLineWidth(@Px int borderWidth) { + checkItemRadius(); mLineWidth = borderWidth; requestLayout(); } @@ -718,6 +733,7 @@ public int getItemCount() { * @see #getItemRadius() */ public void setItemRadius(@Px int itemRadius) { + checkItemRadius(); mPinItemRadius = itemRadius; requestLayout(); } @@ -800,6 +816,7 @@ public float getItemHeight() { * @see #getItemWidth() */ public void setItemWidth(float itemWidth) { + checkItemRadius(); mPinItemWidth = itemWidth; requestLayout(); } From 239cc432e2672aa243d2e1994823f0b6ddb3b38e Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sat, 27 Jan 2018 16:23:14 +0800 Subject: [PATCH 2/8] [Fix] PinView disappears on RTL mode #6, #8, #9 --- pinview/src/main/java/com/chaos/view/PinView.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pinview/src/main/java/com/chaos/view/PinView.java b/pinview/src/main/java/com/chaos/view/PinView.java index 07d17be..5dc6d64 100644 --- a/pinview/src/main/java/com/chaos/view/PinView.java +++ b/pinview/src/main/java/com/chaos/view/PinView.java @@ -31,6 +31,7 @@ import android.support.annotation.ColorInt; import android.support.annotation.Nullable; import android.support.annotation.Px; +import android.support.v4.view.ViewCompat; import android.support.v7.widget.AppCompatEditText; import android.text.InputFilter; import android.text.TextPaint; @@ -206,7 +207,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { width = widthSize; } else { float boxesWidth = (mPinItemCount - 1) * mPinItemSpacing + mPinItemCount * mPinItemWidth; - width = Math.round(boxesWidth + getPaddingRight() + getPaddingLeft()); + width = Math.round(boxesWidth + ViewCompat.getPaddingEnd(this) + ViewCompat.getPaddingStart(this)); if (mPinItemSpacing == 0) { width -= (mPinItemCount - 1) * mLineWidth; } @@ -326,9 +327,9 @@ private void drawPinView(Canvas canvas) { private void drawWholeBoxView(Canvas canvas) { float halfLineWidth = (float) mLineWidth / 2; - float left = getPaddingLeft() + halfLineWidth; - float right = left + getWidth() - getPaddingLeft() - getPaddingRight() - mLineWidth; - float top = getPaddingTop() + halfLineWidth; + float left = getScrollX() + ViewCompat.getPaddingStart(this) + halfLineWidth; + float right = left + getWidth() - ViewCompat.getPaddingStart(this) - ViewCompat.getPaddingEnd(this) - mLineWidth; + float top = getScrollY() + getPaddingTop() + halfLineWidth; float bottom = top + mPinItemHeight - mLineWidth; mItemBorderRect.set(left, top, right, bottom); @@ -433,12 +434,12 @@ private void updateRoundRectPath(RectF rectF, float rx, float ry, private void updateItemRectF(int i) { float halfLineWidth = (float) mLineWidth / 2; - float left = getPaddingLeft() + i * (mPinItemSpacing + mPinItemWidth) + halfLineWidth; + float left = getScrollX() + ViewCompat.getPaddingStart(this) + i * (mPinItemSpacing + mPinItemWidth) + halfLineWidth; if (mPinItemSpacing == 0 && i > 0) { left = left - (mLineWidth) * i; } float right = left + mPinItemWidth - mLineWidth; - float top = getPaddingTop() + halfLineWidth; + float top = getScrollY() + getPaddingTop() + halfLineWidth; float bottom = top + mPinItemHeight - mLineWidth; mItemBorderRect.set(left, top, right, bottom); From 666639dcbc3ba5f381f36afb122e94dc24ebf4ce Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sat, 27 Jan 2018 17:02:41 +0800 Subject: [PATCH 3/8] [Feature] Add highlight configuration for next item #5 --- .../src/main/java/com/chaos/view/PinView.java | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/pinview/src/main/java/com/chaos/view/PinView.java b/pinview/src/main/java/com/chaos/view/PinView.java index 5dc6d64..c66048e 100644 --- a/pinview/src/main/java/com/chaos/view/PinView.java +++ b/pinview/src/main/java/com/chaos/view/PinView.java @@ -291,20 +291,12 @@ private void updatePaints() { } private void drawPinView(Canvas canvas) { - if (mViewType == VIEW_TYPE_RECTANGLE && mPinItemSpacing == 0 && mPinItemCount > 1) { - // because the whole box view draw by updateRoundRectPath() has some bugs we can not fix it, - // so just draw a whole box view - drawWholeBoxView(canvas); - } - for (int i = 0; i < mPinItemCount; i++) { updateItemRectF(i); updateCenterPoint(); if (mViewType == VIEW_TYPE_RECTANGLE) { - if (mPinItemSpacing != 0) { - drawPerPinBox(canvas); - } + drawPinBox(canvas, i); } else { drawPinLine(canvas, i); } @@ -323,6 +315,25 @@ private void drawPinView(Canvas canvas) { drawHint(canvas, i); } } + + // highlight the next item + if (isFocused() && getText().length() != mPinItemCount) { + int index = getText().length(); + updateItemRectF(index); + updateCenterPoint(); + + mPaint.setColor(getLineColorForState(android.R.attr.state_selected)); + + if (mViewType == VIEW_TYPE_RECTANGLE) { + drawPinBox(canvas, index); + } else { + drawPinLine(canvas, index); + } + } + } + + private int getLineColorForState(int... states) { + return mLineColor != null ? mLineColor.getColorForState(states, mCurLineColor) : mCurLineColor; } private void drawWholeBoxView(Canvas canvas) { @@ -343,8 +354,20 @@ private void drawWholeBoxView(Canvas canvas) { canvas.drawPath(mPath, mPaint); } - private void drawPerPinBox(Canvas canvas) { - updateRoundRectPath(mItemBorderRect, mPinItemRadius, mPinItemRadius, true, true); + private void drawPinBox(Canvas canvas, int i) { + boolean drawRightCorner = false; + boolean drawLeftCorner = false; + if (mPinItemSpacing != 0) { + drawLeftCorner = drawRightCorner = true; + } else { + if (i == 0 && i != mPinItemCount - 1) { + drawLeftCorner = true; + } + if (i == mPinItemCount - 1 && i != 0) { + drawRightCorner = true; + } + } + updateRoundRectPath(mItemBorderRect, mPinItemRadius, mPinItemRadius, drawLeftCorner, drawRightCorner); canvas.drawPath(mPath, mPaint); } From 4116e85c280b4ae9ea733748ebf8e00f8f678396 Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sun, 28 Jan 2018 02:23:54 +0800 Subject: [PATCH 4/8] [Feature] Cursor supports #3 --- .../src/main/java/com/chaos/view/PinView.java | 232 +++++++++++++++++- pinview/src/main/res/values/attrs.xml | 3 + pinview/src/main/res/values/dimens.xml | 1 + 3 files changed, 229 insertions(+), 7 deletions(-) diff --git a/pinview/src/main/java/com/chaos/view/PinView.java b/pinview/src/main/java/com/chaos/view/PinView.java index c66048e..ac3255c 100644 --- a/pinview/src/main/java/com/chaos/view/PinView.java +++ b/pinview/src/main/java/com/chaos/view/PinView.java @@ -38,6 +38,7 @@ import android.text.TextUtils; import android.text.method.MovementMethod; import android.util.AttributeSet; +import android.view.View; import android.view.animation.DecelerateInterpolator; import android.view.inputmethod.EditorInfo; @@ -53,6 +54,8 @@ public class PinView extends AppCompatEditText { private static final boolean DBG = false; + private static final int BLINK = 500; + private static final int DEFAULT_COUNT = 4; private static final InputFilter[] NO_FILTERS = new InputFilter[0]; @@ -87,6 +90,13 @@ public class PinView extends AppCompatEditText { private ValueAnimator mDefaultAddAnimator; private boolean isAnimationEnable = false; + private Blink mBlink; + private boolean isCursorVisible; + private boolean drawCursor; + private float mCursorHeight; + private int mCursorWidth; + private int mCursorColor; + public PinView(Context context) { this(context, null); } @@ -140,16 +150,22 @@ public PinView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) if (a.hasValue(R.styleable.PinView_lineColor)) { mLineColor = a.getColorStateList(R.styleable.PinView_lineColor); } + isCursorVisible = a.getBoolean(R.styleable.PinView_android_cursorVisible, true); + mCursorColor = a.getColor(R.styleable.PinView_cursorColor, getCurrentTextColor()); + mCursorWidth = a.getDimensionPixelSize(R.styleable.PinView_cursorWidth, + res.getDimensionPixelSize(R.dimen.pv_pin_view_cursor_width)); a.recycle(); + updateCursorHeight(); + checkItemRadius(); setMaxLength(mPinItemCount); mPaint.setStrokeWidth(mLineWidth); setupAnimator(); - setCursorVisible(false); + super.setCursorVisible(false); setTextIsSelectable(false); } @@ -225,12 +241,12 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { - super.onTextChanged(text, start, lengthBefore, lengthAfter); - if (start != text.length()) { - moveCursorToEnd(); + moveSelectionToEnd(); } + makeBlink(); + if (isAnimationEnable) { final boolean isAdd = lengthAfter - lengthBefore > 0; if (isAdd) { @@ -247,7 +263,8 @@ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFoc super.onFocusChanged(focused, direction, previouslyFocusedRect); if (focused) { - moveCursorToEnd(); + moveSelectionToEnd(); + makeBlink(); } } @@ -256,11 +273,11 @@ protected void onSelectionChanged(int selStart, int selEnd) { super.onSelectionChanged(selStart, selEnd); if (selEnd != getText().length()) { - moveCursorToEnd(); + moveSelectionToEnd(); } } - private void moveCursorToEnd() { + private void moveSelectionToEnd() { setSelection(getText().length()); } @@ -324,6 +341,8 @@ private void drawPinView(Canvas canvas) { mPaint.setColor(getLineColorForState(android.R.attr.state_selected)); + drawCursor(canvas); + if (mViewType == VIEW_TYPE_RECTANGLE) { drawPinBox(canvas, index); } else { @@ -395,6 +414,25 @@ private void drawPinLine(Canvas canvas, int i) { canvas.drawPath(mPath, mPaint); } + private void drawCursor(Canvas canvas) { + if (drawCursor) { + float cx = mItemCenterPoint.x; + float cy = mItemCenterPoint.y; + float x = cx; + float y = cy - mCursorHeight / 2; + + int color = mPaint.getColor(); + float width = mPaint.getStrokeWidth(); + mPaint.setColor(mCursorColor); + mPaint.setStrokeWidth(mCursorWidth); + + canvas.drawLine(x, y, x, y + mCursorHeight, mPaint); + + mPaint.setColor(color); + mPaint.setStrokeWidth(width); + } + } + private void updateRoundRectPath(RectF rectF, float rx, float ry, boolean l, boolean r) { updateRoundRectPath(rectF, rx, ry, l, r, r, l); } @@ -822,6 +860,7 @@ public float getItemSize() { */ public void setItemHeight(float itemHeight) { mPinItemHeight = itemHeight; + updateCursorHeight(); requestLayout(); } @@ -862,4 +901,183 @@ public float getItemWidth() { public void setAnimationEnable(boolean enable) { isAnimationEnable = enable; } + + @Override + public void setTextSize(float size) { + super.setTextSize(size); + updateCursorHeight(); + } + + @Override + public void setTextSize(int unit, float size) { + super.setTextSize(unit, size); + updateCursorHeight(); + } + + //region Cursor + /** + * Sets the width (in pixels) of cursor. + * + * @attr ref R.styleable#PinView_cursorWidth + * @see #getCursorWidth() + */ + public void setCursorWidth(@Px int width) { + checkItemRadius(); + mCursorWidth = width; + if (isCursorVisible()) { + invalidateCursor(true); + } + } + + /** + * @return Returns the width (in pixels) of cursor. + * @see #setCursorWidth(int) + */ + public int getCursorWidth() { + return mCursorWidth; + } + + /** + * Sets the cursor color. + * + * @param color A color value in the form 0xAARRGGBB. + * Do not pass a resource ID. To get a color value from a resource ID, call + * {@link android.support.v4.content.ContextCompat#getColor(Context, int) getColor}. + * @attr ref R.styleable#PinView_cursorColor + * @see #getCursorColor() + */ + public void setCursorColor(@ColorInt int color) { + mCursorColor = color; + if (isCursorVisible()) { + invalidateCursor(true); + } + } + + /** + * Gets the cursor color. + * + * @return Return current cursor color. + * @see #setCursorColor(int) + */ + public int getCursorColor() { + return mCursorColor; + } + + @Override + public void setCursorVisible(boolean visible) { + if (isCursorVisible != visible) { + isCursorVisible = visible; + invalidateCursor(isCursorVisible); + makeBlink(); + } + } + + @Override + public boolean isCursorVisible() { + return isCursorVisible; + } + + @Override + public void onScreenStateChanged(int screenState) { + super.onScreenStateChanged(screenState); + switch (screenState) { + case View.SCREEN_STATE_ON: + resumeBlink(); + break; + case View.SCREEN_STATE_OFF: + suspendBlink(); + break; + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + resumeBlink(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + suspendBlink(); + } + + private boolean shouldBlink() { + return isCursorVisible() && isFocused(); + } + + private void makeBlink() { + if (shouldBlink()) { + if (mBlink == null) { + mBlink = new Blink(); + } + removeCallbacks(mBlink); + drawCursor = false; + postDelayed(mBlink, BLINK); + } else { + if (mBlink != null) { + removeCallbacks(mBlink); + } + } + } + + private void suspendBlink() { + if (mBlink != null) { + mBlink.cancel(); + invalidateCursor(false); + } + } + + private void resumeBlink() { + if (mBlink != null) { + mBlink.uncancel(); + makeBlink(); + } + } + + private void invalidateCursor(boolean showCursor) { + if (drawCursor != showCursor) { + drawCursor = showCursor; + invalidate(); + } + } + + private void updateCursorHeight() { + int delta = 2 * dpToPx(2); + mCursorHeight = mPinItemHeight - getTextSize() > delta ? getTextSize() + delta : getTextSize(); + } + + private class Blink implements Runnable { + private boolean mCancelled; + + @Override + public void run() { + if (mCancelled) { + return; + } + + removeCallbacks(this); + + if (shouldBlink()) { + invalidateCursor(!drawCursor); + postDelayed(this, BLINK); + } + } + + private void cancel() { + if (!mCancelled) { + removeCallbacks(this); + mCancelled = true; + } + } + + void uncancel() { + mCancelled = false; + } + } + //endregion + + private int dpToPx(float dp) { + return (int) (dp * getResources().getDisplayMetrics().density + 0.5f); + } } \ No newline at end of file diff --git a/pinview/src/main/res/values/attrs.xml b/pinview/src/main/res/values/attrs.xml index a722a9d..ceaad1a 100644 --- a/pinview/src/main/res/values/attrs.xml +++ b/pinview/src/main/res/values/attrs.xml @@ -38,5 +38,8 @@ + + + \ No newline at end of file diff --git a/pinview/src/main/res/values/dimens.xml b/pinview/src/main/res/values/dimens.xml index 8fbe171..c841e00 100644 --- a/pinview/src/main/res/values/dimens.xml +++ b/pinview/src/main/res/values/dimens.xml @@ -20,4 +20,5 @@ 5dp 5dp 2dp + 2dp \ No newline at end of file From aa208c14b43a4e043791b5aa75d2910687f08fa2 Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sun, 28 Jan 2018 12:09:09 +0800 Subject: [PATCH 5/8] [Feature] Remove those deprecated methods --- .../src/main/java/com/chaos/view/PinView.java | 136 ++---------------- pinview/src/main/res/values/attrs.xml | 6 - 2 files changed, 10 insertions(+), 132 deletions(-) diff --git a/pinview/src/main/java/com/chaos/view/PinView.java b/pinview/src/main/java/com/chaos/view/PinView.java index ac3255c..44d54ff 100644 --- a/pinview/src/main/java/com/chaos/view/PinView.java +++ b/pinview/src/main/java/com/chaos/view/PinView.java @@ -67,7 +67,6 @@ public class PinView extends AppCompatEditText { private int mPinItemCount; - private float mPinItemSize; private float mPinItemWidth; private float mPinItemHeight; private int mPinItemRadius; @@ -126,30 +125,16 @@ public PinView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) mViewType = a.getInt(R.styleable.PinView_viewType, VIEW_TYPE_RECTANGLE); mPinItemCount = a.getInt(R.styleable.PinView_itemCount, DEFAULT_COUNT); - mPinItemSize = a.getDimensionPixelSize(R.styleable.PinView_itemSize, - res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_size)); - mPinItemHeight = mPinItemWidth = mPinItemSize; - if (a.hasValue(R.styleable.PinView_itemHeight)) { - mPinItemHeight = a.getDimensionPixelOffset(R.styleable.PinView_itemHeight, - res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_size)); - } - if (a.hasValue(R.styleable.PinView_itemWidth)) { - mPinItemWidth = a.getDimensionPixelOffset(R.styleable.PinView_itemWidth, - res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_size)); - } - mPinItemSpacing = a.getDimensionPixelOffset(R.styleable.PinView_itemSpacing, - res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_spacing)); - mPinItemRadius = a.getDimensionPixelOffset(R.styleable.PinView_itemRadius, 0); - mLineWidth = a.getDimensionPixelOffset(R.styleable.PinView_borderWidth, - res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_line_width)); - mLineColor = a.getColorStateList(R.styleable.PinView_borderColor); - if (a.hasValue(R.styleable.PinView_lineWidth)) { - mLineWidth = a.getDimensionPixelOffset(R.styleable.PinView_lineWidth, - res.getDimensionPixelOffset(R.dimen.pv_pin_view_item_line_width)); - } - if (a.hasValue(R.styleable.PinView_lineColor)) { - mLineColor = a.getColorStateList(R.styleable.PinView_lineColor); - } + mPinItemHeight = a.getDimensionPixelSize(R.styleable.PinView_itemHeight, + res.getDimensionPixelSize(R.dimen.pv_pin_view_item_size)); + mPinItemWidth = a.getDimensionPixelSize(R.styleable.PinView_itemWidth, + res.getDimensionPixelSize(R.dimen.pv_pin_view_item_size)); + mPinItemSpacing = a.getDimensionPixelSize(R.styleable.PinView_itemSpacing, + res.getDimensionPixelSize(R.dimen.pv_pin_view_item_spacing)); + mPinItemRadius = a.getDimensionPixelSize(R.styleable.PinView_itemRadius, 0); + mLineWidth = a.getDimensionPixelSize(R.styleable.PinView_lineWidth, + res.getDimensionPixelSize(R.dimen.pv_pin_view_item_line_width)); + mLineColor = a.getColorStateList(R.styleable.PinView_lineColor); isCursorVisible = a.getBoolean(R.styleable.PinView_android_cursorVisible, true); mCursorColor = a.getColor(R.styleable.PinView_cursorColor, getCurrentTextColor()); mCursorWidth = a.getDimensionPixelSize(R.styleable.PinView_cursorWidth, @@ -616,61 +601,6 @@ protected MovementMethod getDefaultMovementMethod() { return null; } - /** - * Sets the border color for all the states (normal, selected, - * focused) to be this color. - * - * @param color A color value in the form 0xAARRGGBB. - * Do not pass a resource ID. To get a color value from a resource ID, call - * {@link android.support.v4.content.ContextCompat#getColor(Context, int) getColor}. - * @attr ref R.styleable#PinView_borderColor - * @see #setBorderColor(ColorStateList) - * @see #getBorderColors() - * @deprecated Use {@link #setLineColor(int)} instead. - */ - @Deprecated - public void setBorderColor(@ColorInt int color) { - setLineColor(color); - } - - /** - * Sets the border color. - * - * @attr ref R.styleable#PinView_borderColor - * @see #setBorderColor(int) - * @see #getBorderColors() - * @deprecated Use {@link #setLineColor(ColorStateList)} instead. - */ - @Deprecated - public void setBorderColor(ColorStateList colors) { - setLineColor(colors); - } - - /** - * Gets the border colors for the different states (normal, selected, focused) of the PinView. - * - * @attr ref R.styleable#PinView_borderColor - * @see #setBorderColor(ColorStateList) - * @see #setBorderColor(int) - * @deprecated Use {@link #getLineColors()} instead. - */ - @Deprecated - public ColorStateList getBorderColors() { - return getLineColors(); - } - - /** - *

Return the current color selected for normal border.

- * - * @return Returns the current border color. - * @deprecated Use {@link #getCurrentLineColor()} instead. - */ - @ColorInt - @Deprecated - public int getCurrentBorderColor() { - return getCurrentLineColor(); - } - /** * Sets the line color for all the states (normal, selected, * focused) to be this color. @@ -724,29 +654,6 @@ public int getCurrentLineColor() { return mCurLineColor; } - /** - * Sets the border width. - * - * @attr ref R.styleable#PinView_borderWidth - * @see #getBorderWidth() - * @deprecated Use {@link #setLineWidth(int)} instead. - */ - @Deprecated - public void setBorderWidth(@Px int borderWidth) { - setLineWidth(borderWidth); - } - - /** - * @return Returns the width of the box's border. - * @see #setBorderWidth(int) - * @deprecated Use {@link #getLineWidth()} instead. - */ - @Px - @Deprecated - public int getBorderWidth() { - return getLineWidth(); - } - /** * Sets the line width. * @@ -829,29 +736,6 @@ public int getItemSpacing() { return mPinItemSpacing; } - /** - * Sets the height and width of item. - * - * @attr ref R.styleable#PinView_itemSize - * @see #getItemSize() - * @deprecated Use {@link #setItemHeight(float)} or {@link #setItemWidth(float)} instead. - */ - @Deprecated - public void setItemSize(float itemSize) { - mPinItemWidth = mPinItemHeight = mPinItemSize = itemSize; - requestLayout(); - } - - /** - * @return Returns the size of item. - * @see #setItemSize(float) - * @deprecated Use {@link #getItemHeight()} or {@link #getItemWidth()} instead. - */ - @Deprecated - public float getItemSize() { - return mPinItemSize; - } - /** * Sets the height of item. * diff --git a/pinview/src/main/res/values/attrs.xml b/pinview/src/main/res/values/attrs.xml index ceaad1a..c400b4b 100644 --- a/pinview/src/main/res/values/attrs.xml +++ b/pinview/src/main/res/values/attrs.xml @@ -22,16 +22,10 @@ - - - - - - From cf177e93ff4e2661d66730fcf3e8769336318700 Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sun, 28 Jan 2018 12:10:58 +0800 Subject: [PATCH 6/8] Upgrade tool chains and modify the minSdkVersion from 14 to 16 --- build.gradle | 11 +++++------ gradle/wrapper/gradle-wrapper.properties | 4 ++-- pinview/build.gradle | 12 ++++++------ simple/build.gradle | 12 ++++++------ 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index e801e89..b1e0e71 100644 --- a/build.gradle +++ b/build.gradle @@ -3,11 +3,12 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' + classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' + classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -16,9 +17,7 @@ buildscript { allprojects { repositories { jcenter() - maven { - url 'https://maven.google.com' - } + google() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d419e57..c9b77cf 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Apr 01 18:57:08 CST 2017 +#Fri Oct 27 10:32:58 CST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip \ No newline at end of file diff --git a/pinview/build.gradle b/pinview/build.gradle index 27be891..c2e9a5b 100644 --- a/pinview/build.gradle +++ b/pinview/build.gradle @@ -17,12 +17,12 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 26 - buildToolsVersion "26.0.1" + compileSdkVersion 27 + buildToolsVersion "27.0.3" defaultConfig { - minSdkVersion 14 - targetSdkVersion 26 + minSdkVersion 16 + targetSdkVersion 27 versionCode 0 versionName "" @@ -39,10 +39,10 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + androidTestCompile('com.android.support.test.espresso:espresso-core:3.0.1', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:26.0.0' + compile 'com.android.support:appcompat-v7:27.0.2' testCompile 'junit:junit:4.12' } diff --git a/simple/build.gradle b/simple/build.gradle index 00653ea..e0f4405 100644 --- a/simple/build.gradle +++ b/simple/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 26 - buildToolsVersion "26.0.1" + compileSdkVersion 27 + buildToolsVersion '27.0.3' defaultConfig { applicationId "com.chaos.view.example" - minSdkVersion 14 - targetSdkVersion 26 + minSdkVersion 16 + targetSdkVersion 27 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -23,10 +23,10 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + androidTestCompile('com.android.support.test.espresso:espresso-core:3.0.1', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:26.0.0' + compile 'com.android.support:appcompat-v7:27.0.2' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' From 63d5fa8469b025bcfc917dbedee8005b5c4adb3d Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sun, 28 Jan 2018 13:15:12 +0800 Subject: [PATCH 7/8] [Fix] Black line color if the color value not stateful --- .../src/main/java/com/chaos/view/PinView.java | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/pinview/src/main/java/com/chaos/view/PinView.java b/pinview/src/main/java/com/chaos/view/PinView.java index 44d54ff..b137a3e 100644 --- a/pinview/src/main/java/com/chaos/view/PinView.java +++ b/pinview/src/main/java/com/chaos/view/PinView.java @@ -142,6 +142,9 @@ public PinView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) a.recycle(); + if (mLineColor != null) { + mCurLineColor = mLineColor.getDefaultColor(); + } updateCursorHeight(); checkItemRadius(); @@ -340,24 +343,6 @@ private int getLineColorForState(int... states) { return mLineColor != null ? mLineColor.getColorForState(states, mCurLineColor) : mCurLineColor; } - private void drawWholeBoxView(Canvas canvas) { - float halfLineWidth = (float) mLineWidth / 2; - float left = getScrollX() + ViewCompat.getPaddingStart(this) + halfLineWidth; - float right = left + getWidth() - ViewCompat.getPaddingStart(this) - ViewCompat.getPaddingEnd(this) - mLineWidth; - float top = getScrollY() + getPaddingTop() + halfLineWidth; - float bottom = top + mPinItemHeight - mLineWidth; - mItemBorderRect.set(left, top, right, bottom); - - updateRoundRectPath(mItemBorderRect, mPinItemRadius, mPinItemRadius, true, true); - - for (int i = 1; i < mPinItemCount; i++) { - mPath.moveTo(mItemBorderRect.left + (mPinItemWidth - mLineWidth) * i, mItemBorderRect.top - mLineWidth / 2); - mPath.rLineTo(0, mPinItemHeight - mLineWidth); - } - - canvas.drawPath(mPath, mPaint); - } - private void drawPinBox(Canvas canvas, int i) { boolean drawRightCorner = false; boolean drawLeftCorner = false; @@ -799,6 +784,7 @@ public void setTextSize(int unit, float size) { } //region Cursor + /** * Sets the width (in pixels) of cursor. * From 4b33e6dcdc87b9e36e5c2335ef27cda43b05b815 Mon Sep 17 00:00:00 2001 From: Chaos Leong Date: Sun, 28 Jan 2018 14:13:49 +0800 Subject: [PATCH 8/8] [Sample] Update smaple and README --- README.md | 41 +++++++++++++++---- .../com/chaos/view/example/MainActivity.java | 10 +++-- simple/src/main/res/color/line_colors.xml | 1 + simple/src/main/res/layout/activity_main.xml | 5 ++- simple/src/main/res/values/colors.xml | 1 + 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a2e1163..7b88d23 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PinView -Provides a widget for enter PIN/OTP/password etc. +Provides a widget for enter PIN/OTP/password etc on Android 4.1+ (API 16).

@@ -15,7 +15,7 @@ repositories { } dependencies { - compile 'com.chaos.view:pinview:1.2.0' + compile 'com.chaos.view:pinview:1.3.0' } ``` @@ -38,6 +38,9 @@ Add PinView in your layout. android:padding="@dimen/common_padding" android:textColor="@color/text_colors" android:textSize="18sp" + android:cursorVisible="true" + app:cursorColor="@color/line_selected" + app:cursorWidth="2dp" app:itemCount="5" app:itemHeight="48dp" app:itemRadius="4dp" @@ -55,11 +58,11 @@ PinView pinView = (PinView) findViewById(R.id.secondPinView); pinView.setTextColor( ResourcesCompat.getColor(getResources(), R.color.colorAccent, getTheme())); pinView.setTextColor( - ResourcesCompat.getColorStateList(getResources(), R.color.line_colors, getTheme())); + ResourcesCompat.getColorStateList(getResources(), R.color.text_colors, getTheme())); pinView.setLineColor( ResourcesCompat.getColor(getResources(), R.color.colorPrimary, getTheme())); pinView.setLineColor( - ResourcesCompat.getColorStateList(getResources(), R.color.text_colors, getTheme())); + ResourcesCompat.getColorStateList(getResources(), R.color.line_colors, getTheme())); pinView.setItemCount(4); pinView.setItemHeight(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_size)); pinView.setItemWidth(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_size)); @@ -67,6 +70,10 @@ pinView.setItemRadius(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_i pinView.setItemSpacing(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_spacing)); pinView.setLineWidth(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_line_width)); pinView.setAnimationEnable(true);// start animation when adding text +pinView.setCursorVisible(false); +pinView.setCursorColor( + ResourcesCompat.getColor(getResources(), R.color.line_selected, getTheme())); +pinView.setCursorWidth(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_cursor_width)); ``` ### Step 2: @@ -90,18 +97,34 @@ or use the `PinWidget.PinView` style. style="@style/PinWidget.PinView" /> ``` +### Step 3 (Optional): + +To highlight current item, + +add `android:state_selected="true"` to `app:lineColor` + +``` xml + + + + + + +``` + +or add `android:cursorVisible="true"`. + ## Attributes -* **itemSize**, @deprecated use itemWidth or itemHeight instead. -* **borderWidth**, @deprecated use lineWidth instead. -* **borderColor**, @deprecated use lineColor instead. * **itemCount**, the length of your pin code. * **itemWidth**, the width of each item. * **itemHeight**, the height of each item. * **itemSpacing**, the spacing between two items. -* **lineWidth**, the line(border) width. -* **lineColor**, the line(border) colors. +* **lineWidth**, the line (border) width. +* **lineColor**, the line (border) colors. * **viewType**, the view type of PinView, currently this will be one of `rectangle` or `line`. +* **cursorColor**, the cursor color. +* **cursorWidth**, the width of cursor. ## Thanks diff --git a/simple/src/main/java/com/chaos/view/example/MainActivity.java b/simple/src/main/java/com/chaos/view/example/MainActivity.java index da1cc52..0dd7127 100644 --- a/simple/src/main/java/com/chaos/view/example/MainActivity.java +++ b/simple/src/main/java/com/chaos/view/example/MainActivity.java @@ -32,15 +32,15 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - PinView pinView = (PinView) findViewById(R.id.secondPinView); + final PinView pinView = findViewById(R.id.secondPinView); pinView.setTextColor( ResourcesCompat.getColor(getResources(), R.color.colorAccent, getTheme())); pinView.setTextColor( - ResourcesCompat.getColorStateList(getResources(), R.color.line_colors, getTheme())); + ResourcesCompat.getColorStateList(getResources(), R.color.text_colors, getTheme())); pinView.setLineColor( ResourcesCompat.getColor(getResources(), R.color.colorPrimary, getTheme())); pinView.setLineColor( - ResourcesCompat.getColorStateList(getResources(), R.color.text_colors, getTheme())); + ResourcesCompat.getColorStateList(getResources(), R.color.line_colors, getTheme())); pinView.setItemCount(4); pinView.setItemHeight(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_size)); pinView.setItemWidth(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_size)); @@ -48,6 +48,10 @@ protected void onCreate(Bundle savedInstanceState) { pinView.setItemSpacing(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_spacing)); pinView.setLineWidth(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_item_line_width)); pinView.setAnimationEnable(true);// start animation when adding text + pinView.setCursorVisible(false); + pinView.setCursorColor( + ResourcesCompat.getColor(getResources(), R.color.line_selected, getTheme())); + pinView.setCursorWidth(getResources().getDimensionPixelSize(R.dimen.pv_pin_view_cursor_width)); } @Override diff --git a/simple/src/main/res/color/line_colors.xml b/simple/src/main/res/color/line_colors.xml index 4c313e7..94d2d84 100644 --- a/simple/src/main/res/color/line_colors.xml +++ b/simple/src/main/res/color/line_colors.xml @@ -16,6 +16,7 @@ --> + \ No newline at end of file diff --git a/simple/src/main/res/layout/activity_main.xml b/simple/src/main/res/layout/activity_main.xml index ab8132a..a5c74bc 100644 --- a/simple/src/main/res/layout/activity_main.xml +++ b/simple/src/main/res/layout/activity_main.xml @@ -35,12 +35,15 @@ android:padding="@dimen/common_padding" android:textColor="@color/text_colors" android:textSize="18sp" + android:cursorVisible="true" + app:cursorColor="@color/line_selected" + app:cursorWidth="2dp" app:itemCount="5" app:itemHeight="48dp" app:itemRadius="4dp" app:itemSpacing="0dp" app:itemWidth="36dp" - app:lineColor="@color/line_colors" + app:lineColor="@color/line_selected" app:lineWidth="2dp" app:viewType="rectangle" /> diff --git a/simple/src/main/res/values/colors.xml b/simple/src/main/res/values/colors.xml index b69725c..78a74dc 100644 --- a/simple/src/main/res/values/colors.xml +++ b/simple/src/main/res/values/colors.xml @@ -23,6 +23,7 @@ #E91E63 #F8BBD0 #BDBDBD + #E91E63 #3F51B5 #C5CAE9