diff --git a/README.md b/README.md index ec22515f..e4f2eebc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-PinLockView-green.svg?style=true)](https://android-arsenal.com/details/1/3706) - # PinLockView -A clean, minimalistic, easy-to-use and highly customizable pin lock custom view for Android +A clean, minimalistic, easy-to-use and highly customizable pin lock custom view for Android. + +### Specs +[ ![Download](https://api.bintray.com/packages/aritraroy/maven/pin-lock-view/images/download.svg) ](https://bintray.com/aritraroy/maven/pin-lock-view/_latestVersion) [![API](https://img.shields.io/badge/API-11%2B-orange.svg?style=flat)](https://android-arsenal.com/api?level=11) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-PinLockView-green.svg?style=true)](https://android-arsenal.com/details/1/3706) ![PinLockView](https://github.com/aritraroy/PinLockView/blob/master/screens/logo.png) @@ -20,7 +21,7 @@ This library is available in **jCenter** which is the default Maven repository u dependencies { // other dependencies here - compile 'com.andrognito.pinlockview:pinlockview:1.0.0' + implementation 'com.andrognito.pinlockview:pinlockview:2.1.0' } ``` @@ -30,7 +31,7 @@ dependencies { com.andrognito.pinlockview pinlockview - 1.0.0 + 2.1.0 pom ``` @@ -40,20 +41,23 @@ We recommend you to **check the sample app** to get a complete understanding of ### Step 1 -Place the view in your layout XML file. +Place the view in your XML layout file. +```xml - +``` ### Step 2 Reference the view in code and add a listener to it. +```java mPinLockView = (PinLockView) findViewById(R.id.pin_lock_view); mPinLockView.setPinLockListener(mPinLockListener); +``` Implement the listener interface as follows, @@ -78,7 +82,7 @@ private PinLockListener mPinLockListener = new PinLockListener() { And that's it! Your PinLockView is ready to rock. -But the good thing is that the, ```PinLockView``` comes with a whole lot of customization options which you can use to customize the view in any way you want. +But the good thing is that the ```PinLockView``` comes with a whole lot of customization options which you can use to customize the view in any way you want. # Customization @@ -125,21 +129,29 @@ There are several theming options available through XML attributes which you can app:dotFilledBackground"@drawable/filled" // Customize the filled state of the dots app:dotDiameter="12dp" // Change the diameter of the dots app:dotSpacing="16dp" // Change the spacing between individual dots + app:indicatorType="fillWithAnimation" // Choose between "fixed", "fill" and "fillWithAnimation" ``` -# Author +# Contribution -**Aritra Roy** - aritra.roy.in@gmail.com -**Play Store** - Andrognito +This library is quite exhaustive and offers a lot of customization options. If you find a bug or would like to improve any aspect of it, feel free to contribute with pull requests. -# Contribution +# About The Author + +### Aritra Roy + +Android & Backend Developer. Blogger. Designer. Fitness Enthusiast. + + + + + -This libary is quite exhaustive and offers a lot of customization options. If you find a bug or would like to improve any aspect of it, feel free to contribute with pull requests. # License ``` -Copyright 2014 aritraroy +Copyright 2017 aritraroy Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/app/build.gradle b/app/build.gradle index 2c1b6319..de9556a1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.3" defaultConfig { applicationId "com.andrognito.pinlockviewapp" - minSdkVersion 14 - targetSdkVersion 23 + minSdkVersion 11 + targetSdkVersion 25 versionCode 1 versionName "1.0" } @@ -22,6 +22,6 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:23.4.0' + compile 'com.android.support:appcompat-v7:25.3.1' compile project(':pinlockview') } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 639bfa3e..f3430dc1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ diff --git a/app/src/main/java/com/andrognito/pinlockviewapp/SampleActivity.java b/app/src/main/java/com/andrognito/pinlockviewapp/SampleActivity.java index 188e22d7..f6414d5a 100644 --- a/app/src/main/java/com/andrognito/pinlockviewapp/SampleActivity.java +++ b/app/src/main/java/com/andrognito/pinlockviewapp/SampleActivity.java @@ -1,6 +1,7 @@ package com.andrognito.pinlockviewapp; import android.os.Bundle; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Window; @@ -38,7 +39,8 @@ public void onPinChange(int pinLength, String intermediatePin) { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_sample); mPinLockView = (PinLockView) findViewById(R.id.pin_lock_view); @@ -46,8 +48,12 @@ protected void onCreate(Bundle savedInstanceState) { mPinLockView.attachIndicatorDots(mIndicatorDots); mPinLockView.setPinLockListener(mPinLockListener); + //mPinLockView.setCustomKeySet(new int[]{2, 3, 1, 5, 9, 6, 7, 0, 8, 4}); + //mPinLockView.enableLayoutShuffling(); - mPinLockView.setPinLength(6); - mPinLockView.setTextColor(getResources().getColor(R.color.white)); + mPinLockView.setPinLength(4); + mPinLockView.setTextColor(ContextCompat.getColor(this, R.color.white)); + + mIndicatorDots.setIndicatorType(IndicatorDots.IndicatorType.FILL_WITH_ANIMATION); } } diff --git a/app/src/main/res/drawable/ic_launcher.png b/app/src/main/res/drawable/ic_launcher.png new file mode 100644 index 00000000..8d94348e Binary files /dev/null and b/app/src/main/res/drawable/ic_launcher.png differ diff --git a/app/src/main/res/layout/activity_sample.xml b/app/src/main/res/layout/activity_sample.xml index f86f1038..05b65c72 100644 --- a/app/src/main/res/layout/activity_sample.xml +++ b/app/src/main/res/layout/activity_sample.xml @@ -1,9 +1,9 @@ @@ -12,7 +12,7 @@ android:layout_width="84dp" android:layout_height="84dp" android:layout_centerHorizontal="true" - android:layout_marginTop="124dp" + android:layout_marginTop="104dp" android:src="@drawable/img_no_avatar" /> + app:keypadTextSize="18dp" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5555c344..f027bdde 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - PinLockViewApp + PinLockViewDemo diff --git a/build.gradle b/build.gradle index 530965f1..b249cff4 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,9 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0' + classpath 'com.android.tools.build:gradle:2.2.3' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4' - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' + classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 122a0dca..660db70a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Dec 28 10:00:20 PST 2015 +#Fri Mar 10 00:08:20 IST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip diff --git a/pinlockview/build.gradle b/pinlockview/build.gradle index a25cc2e1..2fe6adbf 100644 --- a/pinlockview/build.gradle +++ b/pinlockview/build.gradle @@ -4,7 +4,7 @@ ext { bintrayRepo = 'maven' bintrayName = 'pin-lock-view' - publishedGroupId = 'om.andrognito.pinlockview' + publishedGroupId = 'com.andrognito.pinlockview' libraryName = 'pinlockview' artifact = 'pinlockview' @@ -13,7 +13,7 @@ ext { siteUrl = 'https://github.com/aritraroy/PinLockView' gitUrl = 'https://github.com/aritraroy/PinLockView.git' - libraryVersion = '1.0.0' + libraryVersion = '2.1.0' developerId = 'aritraroy' developerName = 'Aritra Roy' @@ -26,14 +26,14 @@ ext { android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.3" defaultConfig { - minSdkVersion 14 - targetSdkVersion 23 - versionCode 1 - versionName "1.0" + minSdkVersion 11 + targetSdkVersion 25 + versionCode 5 + versionName "2.1.0" } buildTypes { release { @@ -46,8 +46,8 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:23.4.0' - compile 'com.android.support:recyclerview-v7:23.4.0' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:recyclerview-v7:25.3.1' } apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle' diff --git a/pinlockview/src/main/AndroidManifest.xml b/pinlockview/src/main/AndroidManifest.xml index 777ea84c..3da35ee3 100644 --- a/pinlockview/src/main/AndroidManifest.xml +++ b/pinlockview/src/main/AndroidManifest.xml @@ -2,8 +2,6 @@ package="com.andrognito.pinlockview"> + android:label="@string/app_name" /> diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/IndicatorDots.java b/pinlockview/src/main/java/com/andrognito/pinlockview/IndicatorDots.java index 7a1b735a..b332d4de 100644 --- a/pinlockview/src/main/java/com/andrognito/pinlockview/IndicatorDots.java +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/IndicatorDots.java @@ -1,19 +1,34 @@ package com.andrognito.pinlockview; +import android.animation.LayoutTransition; import android.content.Context; import android.content.res.TypedArray; +import android.support.annotation.IntDef; +import android.support.v4.view.ViewCompat; import android.util.AttributeSet; import android.view.View; +import android.view.ViewGroup; import android.widget.LinearLayout; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * It represents a set of indicator dots which when attached with {@link PinLockView} * can be used to indicate the current length of the input - * + *

* Created by aritraroy on 01/06/16. */ public class IndicatorDots extends LinearLayout { + @IntDef({IndicatorType.FIXED, IndicatorType.FILL, IndicatorType.FILL_WITH_ANIMATION}) + @Retention(RetentionPolicy.SOURCE) + public @interface IndicatorType { + int FIXED = 0; + int FILL = 1; + int FILL_WITH_ANIMATION = 2; + } + private static final int DEFAULT_PIN_LENGTH = 4; private int mDotDiameter; @@ -21,6 +36,9 @@ public class IndicatorDots extends LinearLayout { private int mFillDrawable; private int mEmptyDrawable; private int mPinLength; + private int mIndicatorType; + + private int mPreviousLength; public IndicatorDots(Context context) { this(context, null); @@ -38,57 +56,88 @@ public IndicatorDots(Context context, AttributeSet attrs, int defStyleAttr) { try { mDotDiameter = (int) typedArray.getDimension(R.styleable.PinLockView_dotDiameter, ResourceUtils.getDimensionInPx(getContext(), R.dimen.default_dot_diameter)); mDotSpacing = (int) typedArray.getDimension(R.styleable.PinLockView_dotSpacing, ResourceUtils.getDimensionInPx(getContext(), R.dimen.default_dot_spacing)); - mFillDrawable = typedArray.getResourceId(R.styleable.PinLockView_dotFilledBackground, R.drawable.dot_filled); - mEmptyDrawable = typedArray.getResourceId(R.styleable.PinLockView_dotEmptyBackground, R.drawable.dot_empty); + mFillDrawable = typedArray.getResourceId(R.styleable.PinLockView_dotFilledBackground, + R.drawable.dot_filled); + mEmptyDrawable = typedArray.getResourceId(R.styleable.PinLockView_dotEmptyBackground, + R.drawable.dot_empty); mPinLength = typedArray.getInt(R.styleable.PinLockView_pinLength, DEFAULT_PIN_LENGTH); + mIndicatorType = typedArray.getInt(R.styleable.PinLockView_indicatorType, + IndicatorType.FIXED); } finally { typedArray.recycle(); } - initDots(context); + initView(context); } - private void initDots(Context context) { - - for (int i = 0; i < mPinLength; i++) { + private void initView(Context context) { + ViewCompat.setLayoutDirection(this, ViewCompat.LAYOUT_DIRECTION_LTR); + if (mIndicatorType == 0) { + for (int i = 0; i < mPinLength; i++) { + View dot = new View(context); + emptyDot(dot); - View dot = new View(context); - emptyDot(dot); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mDotDiameter, + mDotDiameter); + params.setMargins(mDotSpacing, 0, mDotSpacing, 0); + dot.setLayoutParams(params); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mDotDiameter, mDotDiameter); - params.setMargins(mDotSpacing, 0, mDotSpacing, 0); - dot.setLayoutParams(params); + addView(dot); + } + } else if (mIndicatorType == 2) { + setLayoutTransition(new LayoutTransition()); + } + } - addView(dot); + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + // If the indicator type is not fixed + if (mIndicatorType != 0) { + ViewGroup.LayoutParams params = this.getLayoutParams(); + params.height = mDotDiameter; + requestLayout(); } } void updateDot(int length) { - - if (length > 0) { - - for (int i = 0; i < getChildCount(); i++) { - View v = getChildAt(i); - emptyDot(v); - } - - for (int i = 0; i < length; i++) { - View v = getChildAt(i); - if (v != null) { - fillDot(v); + if (mIndicatorType == 0) { + if (length > 0) { + if (length > mPreviousLength) { + fillDot(getChildAt(length - 1)); + } else { + emptyDot(getChildAt(length)); + } + mPreviousLength = length; + } else { + // When {@code mPinLength} is 0, we need to reset all the views back to empty + for (int i = 0; i < getChildCount(); i++) { + View v = getChildAt(i); + emptyDot(v); } + mPreviousLength = 0; } } else { - - /** - * When {@code mPinLength} is 0, we need to reset all the views back to empty - */ - for (int i = 0; i < getChildCount(); i++) { - View v = getChildAt(i); - emptyDot(v); + if (length > 0) { + if (length > mPreviousLength) { + View dot = new View(getContext()); + fillDot(dot); + + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mDotDiameter, + mDotDiameter); + params.setMargins(mDotSpacing, 0, mDotSpacing, 0); + dot.setLayoutParams(params); + + addView(dot, length - 1); + } else { + removeViewAt(length); + } + mPreviousLength = length; + } else { + removeAllViews(); + mPreviousLength = 0; } } - } private void emptyDot(View dot) { @@ -106,6 +155,18 @@ public int getPinLength() { public void setPinLength(int pinLength) { this.mPinLength = pinLength; removeAllViews(); - initDots(getContext()); + initView(getContext()); + } + + public + @IndicatorType + int getIndicatorType() { + return mIndicatorType; + } + + public void setIndicatorType(@IndicatorType int type) { + this.mIndicatorType = type; + removeAllViews(); + initView(getContext()); } } diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/LTRGridLayoutManager.java b/pinlockview/src/main/java/com/andrognito/pinlockview/LTRGridLayoutManager.java new file mode 100644 index 00000000..eac00a54 --- /dev/null +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/LTRGridLayoutManager.java @@ -0,0 +1,31 @@ +package com.andrognito.pinlockview; + +import android.content.Context; +import android.support.v7.widget.GridLayoutManager; +import android.util.AttributeSet; + +/** + * Used to always maintain an LTR layout no matter what is the real device's layout direction + * to avoid an unwanted reversed direction in RTL devices + * Created by Idan on 7/6/2017. + */ + +public class LTRGridLayoutManager extends GridLayoutManager { + + public LTRGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public LTRGridLayoutManager(Context context, int spanCount) { + super(context, spanCount); + } + + public LTRGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { + super(context, spanCount, orientation, reverseLayout); + } + + @Override + protected boolean isLayoutRTL(){ + return false; + } +} diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java index 223f95c0..1df5c3a7 100644 --- a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockAdapter.java @@ -28,8 +28,11 @@ public class PinLockAdapter extends RecyclerView.Adapter 0) { + mDeleteButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mOnDeleteClickListener != null) { + mOnDeleteClickListener.onDeleteClicked(); + } } - } - }); + }); - mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - if (mOnDeleteClickListener != null) { - mOnDeleteClickListener.onDeleteLongClicked(); + mDeleteButton.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (mOnDeleteClickListener != null) { + mOnDeleteClickListener.onDeleteLongClicked(); + } + return true; } - return true; - } - }); + }); - mDeleteButton.setOnTouchListener(new View.OnTouchListener() { - private Rect rect; + mDeleteButton.setOnTouchListener(new View.OnTouchListener() { + private Rect rect; - @Override - public boolean onTouch(View v, MotionEvent event) { - if(event.getAction() == MotionEvent.ACTION_DOWN){ - mButtonImage.setColorFilter(mCustomizationOptionsBundle.getDeleteButtonPressesColor()); - rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); - } - if(event.getAction() == MotionEvent.ACTION_UP){ - mButtonImage.clearColorFilter(); - } - if(event.getAction() == MotionEvent.ACTION_MOVE){ - if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){ + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + mButtonImage.setColorFilter(mCustomizationOptionsBundle + .getDeleteButtonPressesColor()); + rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); + } + if (event.getAction() == MotionEvent.ACTION_UP) { mButtonImage.clearColorFilter(); } + if (event.getAction() == MotionEvent.ACTION_MOVE) { + if (!rect.contains(v.getLeft() + (int) event.getX(), + v.getTop() + (int) event.getY())) { + mButtonImage.clearColorFilter(); + } + } + return false; } - return false; - } - }); + }); + } } } public interface OnNumberClickListener { - void onNumberClicked(int position); + void onNumberClicked(int keyValue); } public interface OnDeleteClickListener { diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java index 7815d375..72eade71 100644 --- a/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/PinLockView.java @@ -4,7 +4,6 @@ import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; -import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; @@ -19,6 +18,7 @@ public class PinLockView extends RecyclerView { private static final int DEFAULT_PIN_LENGTH = 4; + private static final int[] DEFAULT_KEY_SET = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; private String mPin = ""; private int mPinLength; @@ -33,13 +33,14 @@ public class PinLockView extends RecyclerView { private PinLockAdapter mAdapter; private PinLockListener mPinLockListener; private CustomizationOptionsBundle mCustomizationOptionsBundle; + private int[] mCustomKeySet; - private PinLockAdapter.OnNumberClickListener mOnNumberClickListener = new PinLockAdapter.OnNumberClickListener() { + private PinLockAdapter.OnNumberClickListener mOnNumberClickListener + = new PinLockAdapter.OnNumberClickListener() { @Override - public void onNumberClicked(int position) { - String key = getData(position); + public void onNumberClicked(int keyValue) { if (mPin.length() < getPinLength()) { - mPin = mPin.concat(key); + mPin = mPin.concat(String.valueOf(keyValue)); if (isIndicatorDotsAttached()) { mIndicatorDots.updateDot(mPin.length()); @@ -60,7 +61,7 @@ public void onNumberClicked(int position) { } else { if (!isShowDeleteButton()) { resetPinLockView(); - mPin = mPin.concat(key); + mPin = mPin.concat(String.valueOf(keyValue)); if (isIndicatorDotsAttached()) { mIndicatorDots.updateDot(mPin.length()); @@ -79,7 +80,8 @@ public void onNumberClicked(int position) { } }; - private PinLockAdapter.OnDeleteClickListener mOnDeleteClickListener = new PinLockAdapter.OnDeleteClickListener() { + private PinLockAdapter.OnDeleteClickListener mOnDeleteClickListener + = new PinLockAdapter.OnDeleteClickListener() { @Override public void onDeleteClicked() { if (mPin.length() > 0) { @@ -167,7 +169,7 @@ private void init(AttributeSet attributeSet, int defStyle) { } private void initView() { - setLayoutManager(new GridLayoutManager(getContext(), 3)); + setLayoutManager(new LTRGridLayoutManager(getContext(), 3)); mAdapter = new PinLockAdapter(getContext()); mAdapter.setOnItemClickListener(mOnNumberClickListener); @@ -370,6 +372,26 @@ public void setDeleteButtonPressedColor(int deleteButtonPressedColor) { mAdapter.notifyDataSetChanged(); } + public int[] getCustomKeySet() { + return mCustomKeySet; + } + + public void setCustomKeySet(int[] customKeySet) { + this.mCustomKeySet = customKeySet; + + if (mAdapter != null) { + mAdapter.setKeyValues(customKeySet); + } + } + + public void enableLayoutShuffling() { + this.mCustomKeySet = ShuffleArrayUtils.shuffle(DEFAULT_KEY_SET); + + if (mAdapter != null) { + mAdapter.setKeyValues(mCustomKeySet); + } + } + private void clearInternalPin() { mPin = ""; } @@ -382,6 +404,9 @@ public void resetPinLockView() { clearInternalPin(); + mAdapter.setPinLength(mPin.length()); + mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1); + if (mIndicatorDots != null) { mIndicatorDots.updateDot(mPin.length()); } @@ -404,10 +429,4 @@ public boolean isIndicatorDotsAttached() { public void attachIndicatorDots(IndicatorDots mIndicatorDots) { this.mIndicatorDots = mIndicatorDots; } - - public String getData(int position) { - if (position == 10) - return "0"; - return String.valueOf((position + 1) % 10); - } } diff --git a/pinlockview/src/main/java/com/andrognito/pinlockview/ShuffleArrayUtils.java b/pinlockview/src/main/java/com/andrognito/pinlockview/ShuffleArrayUtils.java new file mode 100644 index 00000000..9475a946 --- /dev/null +++ b/pinlockview/src/main/java/com/andrognito/pinlockview/ShuffleArrayUtils.java @@ -0,0 +1,33 @@ +package com.andrognito.pinlockview; + +import java.util.Random; + +/** + * Created by aritraroy on 10/03/17. + */ + +public class ShuffleArrayUtils { + + /** + * Shuffle an array + * + * @param array + */ + static int[] shuffle(int[] array) { + int length = array.length; + Random random = new Random(); + random.nextInt(); + + for (int i = 0; i < length; i++) { + int change = i + random.nextInt(length - i); + swap(array, i, change); + } + return array; + } + + private static void swap(int[] array, int index, int change) { + int temp = array[index]; + array[index] = array[change]; + array[change] = temp; + } +} \ No newline at end of file diff --git a/pinlockview/src/main/res/layout-v21/layout_number_item.xml b/pinlockview/src/main/res/layout-v21/layout_number_item.xml new file mode 100644 index 00000000..e96e7fe8 --- /dev/null +++ b/pinlockview/src/main/res/layout-v21/layout_number_item.xml @@ -0,0 +1,15 @@ + + + +