diff --git a/app/src/main/res/layout/activity_sample.xml b/app/src/main/res/layout/activity_sample.xml index 05b65c72..7f8fb202 100644 --- a/app/src/main/res/layout/activity_sample.xml +++ b/app/src/main/res/layout/activity_sample.xml @@ -47,6 +47,8 @@ app:keypadButtonSize="72dp" app:keypadShowDeleteButton="true" app:keypadTextColor="@color/white" - app:keypadTextSize="18dp" /> + app:keypadTextSize="18dp" + app:keypadShowEnterButton="true" + app:keypadSwapEnterDeleteButtons="true"/> diff --git a/build.gradle b/build.gradle index b249cff4..2976defb 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' + classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 660db70a..568ab3c4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Mar 10 00:08:20 IST 2017 +#Tue Dec 12 09:32:28 EET 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.1-all.zip diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/CustomizationOptionsBundle.java b/pinlockview/src/main/java/com/andrognito/pinlockview/CustomizationOptionsBundle.java index 63eee73e..329ce4c3 100644 --- a/pinlockview/src/main/java/com/andrognito/pinlockview/CustomizationOptionsBundle.java +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/CustomizationOptionsBundle.java @@ -5,7 +5,7 @@ /** * The customization options for the buttons in {@link PinLockView} * passed to the {@link PinLockAdapter} to decorate the individual views - * + *

* Created by aritraroy on 01/06/16. */ public class CustomizationOptionsBundle { @@ -19,6 +19,10 @@ public class CustomizationOptionsBundle { private boolean showDeleteButton; private int deleteButtonPressesColor; + private boolean showEnterButton; + private int pinLength; + private boolean swapEnterDeleteButtons; + public CustomizationOptionsBundle() { } @@ -85,4 +89,28 @@ public int getDeleteButtonPressesColor() { public void setDeleteButtonPressesColor(int deleteButtonPressesColor) { this.deleteButtonPressesColor = deleteButtonPressesColor; } + + public boolean isShowEnterButton() { + return showEnterButton; + } + + public void setShowEnterButton(boolean showEnterButton) { + this.showEnterButton = showEnterButton; + } + + public int getPinLength() { + return pinLength; + } + + public void setPinLength(int pinLength) { + this.pinLength = pinLength; + } + + public boolean isSwapEnterDeleteButtons() { + return swapEnterDeleteButtons; + } + + public void setSwapEnterDeleteButtons(boolean swapEnterDeleteButtons) { + this.swapEnterDeleteButtons = swapEnterDeleteButtons; + } } diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java index 1df5c3a7..7689a974 100644 --- a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java @@ -21,11 +21,18 @@ public class PinLockAdapter extends RecyclerView.Adapter= mCustomizationOptionsBundle.getPinLength()) { + holder.mEnterButton.setVisibility(View.VISIBLE); + + if (mCustomizationOptionsBundle != null) { + holder.mEnterButton.setTextColor(mCustomizationOptionsBundle.getTextColor()); + if (mCustomizationOptionsBundle.getButtonBackgroundDrawable() != null) { + if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { + holder.mEnterButton.setBackgroundDrawable( + mCustomizationOptionsBundle.getButtonBackgroundDrawable()); + } else { + holder.mEnterButton.setBackground( + mCustomizationOptionsBundle.getButtonBackgroundDrawable()); + } + } + holder.mEnterButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, + mCustomizationOptionsBundle.getTextSize()); + } + } else { + holder.mEnterButton.setVisibility(View.GONE); + } + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( + mCustomizationOptionsBundle.getButtonSize(), + mCustomizationOptionsBundle.getButtonSize()); + holder.mEnterButton.setLayoutParams(params); } } @@ -118,7 +164,10 @@ public int getItemCount() { @Override public int getItemViewType(int position) { - if (position == getItemCount() - 1) { + if (position == getEnterButtonPosition()) { + return VIEW_TYPE_ENTER; + } + if (position == getDeleteButtonPosition()) { return VIEW_TYPE_DELETE; } return VIEW_TYPE_NUMBER; @@ -170,12 +219,34 @@ public void setOnDeleteClickListener(OnDeleteClickListener onDeleteClickListener this.mOnDeleteClickListener = onDeleteClickListener; } + public void setOnEnterClickListener(OnEnterClickListener onEnterClickListener) { + this.mOnEnterClickListener = onEnterClickListener; + } + public CustomizationOptionsBundle getCustomizationOptions() { return mCustomizationOptionsBundle; } public void setCustomizationOptions(CustomizationOptionsBundle customizationOptionsBundle) { this.mCustomizationOptionsBundle = customizationOptionsBundle; + setEnterButtonPosition(mCustomizationOptionsBundle.isSwapEnterDeleteButtons() ? 11 : 9); + setDeleteButtonPosition(mCustomizationOptionsBundle.isSwapEnterDeleteButtons() ? 9 : 11); + } + + public int getEnterButtonPosition() { + return enterButtonPosition; + } + + public void setEnterButtonPosition(int enterButtonPosition) { + this.enterButtonPosition = enterButtonPosition; + } + + public int getDeleteButtonPosition() { + return deleteButtonPosition; + } + + public void setDeleteButtonPosition(int deleteButtonPosition) { + this.deleteButtonPosition = deleteButtonPosition; } public class NumberViewHolder extends RecyclerView.ViewHolder { @@ -250,6 +321,23 @@ public boolean onTouch(View v, MotionEvent event) { } } + public class EnterViewHolder extends RecyclerView.ViewHolder { + Button mEnterButton; + + public EnterViewHolder(final View itemView) { + super(itemView); + mEnterButton = (Button) itemView.findViewById(R.id.button); + mEnterButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mOnEnterClickListener != null) { + mOnEnterClickListener.onEnterClicked(); + } + } + }); + } + } + public interface OnNumberClickListener { void onNumberClicked(int keyValue); } @@ -259,4 +347,8 @@ public interface OnDeleteClickListener { void onDeleteLongClicked(); } + + public interface OnEnterClickListener { + void onEnterClicked(); + } } diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java index 72eade71..4f347197 100644 --- a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java @@ -29,6 +29,9 @@ public class PinLockView extends RecyclerView { private Drawable mDeleteButtonDrawable; private boolean mShowDeleteButton; + private boolean mShowEnterButton; + private boolean mSwapEnterDeleteButtons; + private IndicatorDots mIndicatorDots; private PinLockAdapter mAdapter; private PinLockListener mPinLockListener; @@ -39,7 +42,7 @@ public class PinLockView extends RecyclerView { = new PinLockAdapter.OnNumberClickListener() { @Override public void onNumberClicked(int keyValue) { - if (mPin.length() < getPinLength()) { + if (mPin.length() < getPinLength() || mShowEnterButton) { mPin = mPin.concat(String.valueOf(keyValue)); if (isIndicatorDotsAttached()) { @@ -48,11 +51,16 @@ public void onNumberClicked(int keyValue) { if (mPin.length() == 1) { mAdapter.setPinLength(mPin.length()); - mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1); + mAdapter.notifyItemChanged(mAdapter.getDeleteButtonPosition()); + } + + if (mPin.length() == mPinLength) { + mAdapter.setPinLength(mPin.length()); + mAdapter.notifyItemChanged(mAdapter.getEnterButtonPosition()); } if (mPinLockListener != null) { - if (mPin.length() == mPinLength) { + if (mPin.length() == mPinLength && !mShowEnterButton) { mPinLockListener.onComplete(mPin); } else { mPinLockListener.onPinChange(mPin.length(), mPin); @@ -73,7 +81,9 @@ public void onNumberClicked(int keyValue) { } else { if (mPinLockListener != null) { - mPinLockListener.onComplete(mPin); + if (!mShowEnterButton) { + mPinLockListener.onComplete(mPin); + } } } } @@ -93,7 +103,12 @@ public void onDeleteClicked() { if (mPin.length() == 0) { mAdapter.setPinLength(mPin.length()); - mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1); + mAdapter.notifyItemChanged(mAdapter.getDeleteButtonPosition()); + } + + if (mPin.length() == mPinLength - 1) { + mAdapter.setPinLength(mPin.length()); + mAdapter.notifyItemChanged(mAdapter.getEnterButtonPosition()); } if (mPinLockListener != null) { @@ -120,6 +135,16 @@ public void onDeleteLongClicked() { } }; + private PinLockAdapter.OnEnterClickListener mOnEnterClickListener + = new PinLockAdapter.OnEnterClickListener() { + @Override + public void onEnterClicked() { + if (mPin.length() >= mPinLength) { + mPinLockListener.onComplete(mPin); + } + } + }; + public PinLockView(Context context) { super(context); init(null, 0); @@ -151,6 +176,12 @@ private void init(AttributeSet attributeSet, int defStyle) { mDeleteButtonDrawable = typedArray.getDrawable(R.styleable.PinLockView_keypadDeleteButtonDrawable); mShowDeleteButton = typedArray.getBoolean(R.styleable.PinLockView_keypadShowDeleteButton, true); mDeleteButtonPressedColor = typedArray.getColor(R.styleable.PinLockView_keypadDeleteButtonPressedColor, ResourceUtils.getColor(getContext(), R.color.greyish)); + + mShowEnterButton = typedArray.getBoolean(R.styleable.PinLockView_keypadShowEnterButton, false); + if (mShowEnterButton) { + mShowDeleteButton = true; + } + mSwapEnterDeleteButtons = typedArray.getBoolean(R.styleable.PinLockView_keypadSwapEnterDeleteButtons, false); } finally { typedArray.recycle(); } @@ -165,6 +196,9 @@ private void init(AttributeSet attributeSet, int defStyle) { mCustomizationOptionsBundle.setShowDeleteButton(mShowDeleteButton); mCustomizationOptionsBundle.setDeleteButtonPressesColor(mDeleteButtonPressedColor); + mCustomizationOptionsBundle.setShowEnterButton(mShowEnterButton); + mCustomizationOptionsBundle.setPinLength(mPinLength); + mCustomizationOptionsBundle.setSwapEnterDeleteButtons(mSwapEnterDeleteButtons); initView(); } @@ -174,6 +208,9 @@ private void initView() { mAdapter = new PinLockAdapter(getContext()); mAdapter.setOnItemClickListener(mOnNumberClickListener); mAdapter.setOnDeleteClickListener(mOnDeleteClickListener); + + mAdapter.setOnEnterClickListener(mOnEnterClickListener); + mAdapter.setCustomizationOptions(mCustomizationOptionsBundle); setAdapter(mAdapter); @@ -206,6 +243,7 @@ public int getPinLength() { */ public void setPinLength(int pinLength) { this.mPinLength = pinLength; + mCustomizationOptionsBundle.setPinLength(mPinLength); if (isIndicatorDotsAttached()) { mIndicatorDots.setPinLength(pinLength); @@ -405,7 +443,8 @@ public void resetPinLockView() { clearInternalPin(); mAdapter.setPinLength(mPin.length()); - mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1); + mAdapter.notifyItemChanged(mAdapter.getEnterButtonPosition()); + mAdapter.notifyItemChanged(mAdapter.getDeleteButtonPosition()); if (mIndicatorDots != null) { mIndicatorDots.updateDot(mPin.length()); diff --git a/pinlockview/src/main/res/layout/layout_enter_item.xml b/pinlockview/src/main/res/layout/layout_enter_item.xml new file mode 100644 index 00000000..fed29c6a --- /dev/null +++ b/pinlockview/src/main/res/layout/layout_enter_item.xml @@ -0,0 +1,16 @@ + + + +