diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index c1ffde8..ba1611c 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 30aa626..30795ec 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,5 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -25,5 +93,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+ ^$
+
+
+
+
+
+
+
+
+ style
+ ^$
+
+
+
+
+
+
+
+
+ .*
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:layout_width
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:layout_height
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:layout_.*
+ http://schemas.android.com/apk/res/android
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:width
+ http://schemas.android.com/apk/res/android
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:height
+ http://schemas.android.com/apk/res/android
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+ http://schemas.android.com/apk/res/android
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..2c7451d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/buildSrc/src/dependencies.kt b/buildSrc/src/dependencies.kt
index 42ac0c2..bfeb99f 100644
--- a/buildSrc/src/dependencies.kt
+++ b/buildSrc/src/dependencies.kt
@@ -10,17 +10,6 @@ fun DependencyHandler.androidx(
version: String = VERSION_ANDROIDX
): String = "androidx.$repository:$module:$version"
-fun DependencyHandler.hendraanggrian(
- repository: String,
- module: String = repository,
- version: String
-): String = "com.hendraanggrian.$repository:$module:$version"
-
-fun DependencyHandler.jakeWharton(
- module: String,
- version: String
-): String = "com.jakewharton:$module:$version"
-
fun DependencyHandler.material() = "com.google.android.material:material:$VERSION_ANDROIDX"
fun DependencyHandler.junit() = "junit:junit:$VERSION_JUNIT"
diff --git a/buildSrc/src/releases.kt b/buildSrc/src/releases.kt
index 7aef11e..e55d5f1 100644
--- a/buildSrc/src/releases.kt
+++ b/buildSrc/src/releases.kt
@@ -2,7 +2,7 @@ const val RELEASE_USER = "hendraanggrian"
const val RELEASE_REPO = "appcompat"
const val RELEASE_GROUP = "com.$RELEASE_USER.$RELEASE_REPO"
const val RELEASE_ARTIFACT = "pinview"
-const val RELEASE_VERSION = "0.1"
+const val RELEASE_VERSION = "0.2"
const val RELEASE_DESC = "Android customizable PIN input view"
const val RELEASE_WEBSITE = "https://github.com/$RELEASE_USER/$RELEASE_ARTIFACT"
diff --git a/buildSrc/src/versions.kt b/buildSrc/src/versions.kt
index 1b1a221..b1117d1 100644
--- a/buildSrc/src/versions.kt
+++ b/buildSrc/src/versions.kt
@@ -11,10 +11,7 @@ const val VERSION_ESPRESSO = "3.1.0-alpha4"
const val VERSION_RUNNER = "1.1.0-alpha4"
const val VERSION_RULES = "1.1.0-alpha4"
-const val VERSION_PROCESS_PHOENIX = "2.0.0"
-const val VERSION_BUNDLER = "0.2"
-
internal const val VERSION_TRUTH = "0.42"
internal const val VERSION_JUNIT = "4.12"
internal const val VERSION_GIT_PUBLISH = "0.3.3"
-internal const val VERSION_BINTRAY_RELEASE = "0.8.1"
+internal const val VERSION_BINTRAY_RELEASE = "0.8.1"
\ No newline at end of file
diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts
index 87a9b84..5b1a5dc 100644
--- a/demo/build.gradle.kts
+++ b/demo/build.gradle.kts
@@ -49,8 +49,4 @@ dependencies {
implementation(androidx("appcompat"))
implementation(androidx("coordinatorlayout"))
implementation(androidx("preference"))
-
- implementation(jakeWharton("process-phoenix", VERSION_PROCESS_PHOENIX))
- implementation(hendraanggrian("bundler", version = VERSION_BUNDLER))
- kapt(hendraanggrian("bundler", "bundler-compiler", VERSION_BUNDLER))
}
\ No newline at end of file
diff --git a/demo/src/com/hendraanggrian/appcompat/pinview/demo/DemoActivity.kt b/demo/src/com/hendraanggrian/appcompat/pinview/demo/DemoActivity.kt
index 021bb6f..00e8b2a 100644
--- a/demo/src/com/hendraanggrian/appcompat/pinview/demo/DemoActivity.kt
+++ b/demo/src/com/hendraanggrian/appcompat/pinview/demo/DemoActivity.kt
@@ -37,7 +37,10 @@ class DemoActivity : AppCompatActivity() {
preferences = PreferenceManager.getDefaultSharedPreferences(this)
pinView.setOnPinChangedListener(pinListener)
pinView.setOnStateChangedListener(stateListener)
+
stateListener.onStateChanged(pinView, false)
+ preferenceListener.onSharedPreferenceChanged(preferences, PREFERENCE_COUNT)
+ preferenceListener.onSharedPreferenceChanged(preferences, PREFERENCE_GAP)
}
override fun onResume() {
diff --git a/pinview/src/com/hendraanggrian/appcompat/widget/PinView.java b/pinview/src/com/hendraanggrian/appcompat/widget/PinView.java
index ad6232b..563c8f0 100644
--- a/pinview/src/com/hendraanggrian/appcompat/widget/PinView.java
+++ b/pinview/src/com/hendraanggrian/appcompat/widget/PinView.java
@@ -9,7 +9,6 @@
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
-import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -19,8 +18,10 @@
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.Px;
import androidx.annotation.StringRes;
import androidx.annotation.StyleRes;
+import androidx.core.util.Consumer;
import androidx.core.widget.TextViewCompat;
public class PinView extends LinearLayout {
@@ -50,7 +51,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
@Override
public void afterTextChanged(Editable s) {
- if (!TextUtils.isEmpty(s) && focusedPin < getChildCount() - 1) {
+ if (!TextUtils.isEmpty(s) && focusedPin < getCount() - 1) {
getPinAt(focusedPin + 1).requestFocus();
} else if (TextUtils.isEmpty(s) && focusedPin > 0) {
getPinAt(focusedPin - 1).requestFocus();
@@ -82,17 +83,17 @@ public PinView(@NonNull Context context, @Nullable AttributeSet attrs) {
}
public PinView(
- @NonNull Context context,
- @Nullable AttributeSet attrs,
- @AttrRes int defStyleAttr
+ @NonNull Context context,
+ @Nullable AttributeSet attrs,
+ @AttrRes int defStyleAttr
) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(
- attrs,
- R.styleable.PinView,
- defStyleAttr,
- R.style.Widget_PinView
+ attrs,
+ R.styleable.PinView,
+ defStyleAttr,
+ R.style.Widget_PinView
);
setCount(a.getInt(R.styleable.PinView_pinCount, DEFAULT_COUNT));
setGap(a.getDimensionPixelSize(R.styleable.PinView_pinGap, 0));
@@ -134,28 +135,13 @@ public TextView getPinAt(int index) {
return (PinEditText) getChildAt(index);
}
- private void applyGap() {
- if (pinGap > 0 && getChildCount() > 1) {
- for (int i = 0; i < getChildCount(); i++) {
- final MarginLayoutParams lp = (MarginLayoutParams) getChildAt(i).getLayoutParams();
- final int gapStart = i == 0 ? 0 : pinGap / 2;
- final int gapEnd = i == getChildCount() - 1 ? 0 : pinGap / 2;
- if (Build.VERSION.SDK_INT >= 17) {
- lp.setMarginStart(gapStart);
- lp.setMarginEnd(gapEnd);
- } else {
- lp.setMargins(gapStart, 0, gapEnd, 0);
- }
- }
- }
- }
-
public void setCount(int count) {
- if (getChildCount() > count) {
- removeViews(count, getChildCount() - count);
- } else if (getChildCount() < count) {
- for (int i = 0; i < count - getChildCount(); i++) {
- EditText view = new PinEditText(getContext());
+ final int diff = count - getCount();
+ if (diff < 0) {
+ removeViews(count, -diff);
+ } else if (diff > 0) {
+ for (int i = 0; i < diff; i++) {
+ TextView view = new PinEditText(getContext());
view.setOnFocusChangeListener(focusListener);
view.addTextChangedListener(textWatcher);
addView(view);
@@ -167,11 +153,12 @@ public int getCount() {
return getChildCount();
}
- public void setGap(int gap) {
+ public void setGap(@Px int gap) {
pinGap = gap;
applyGap();
}
+ @Px
public int getGap() {
return pinGap;
}
@@ -201,40 +188,62 @@ public void setText(@StringRes int res) {
@NonNull
public CharSequence getText() {
final StringBuilder builder = new StringBuilder();
- for (int i = 0; i < getChildCount(); i++) {
- builder.append(getPinAt(i).getText());
- }
+ forEach(new Consumer() {
+ @Override
+ public void accept(TextView textView) {
+ builder.append(textView.getText());
+ }
+ });
return builder.toString();
}
- public void setTextAppearance(@StyleRes int res) {
- for (int i = 0; i < getChildCount(); i++) {
- TextViewCompat.setTextAppearance(getPinAt(i), res);
- }
+ public void setTextAppearance(@StyleRes final int res) {
+ forEach(new Consumer() {
+ @Override
+ public void accept(TextView textView) {
+ if (Build.VERSION.SDK_INT >= 23) {
+ textView.setTextAppearance(res);
+ } else {
+ TextViewCompat.setTextAppearance(textView, res);
+ }
+ }
+ });
}
- public void setTextColor(@ColorInt int color) {
- for (int i = 0; i < getChildCount(); i++) {
- getPinAt(i).setTextColor(color);
- }
+ public void setTextColor(@ColorInt final int color) {
+ forEach(new Consumer() {
+ @Override
+ public void accept(TextView textView) {
+ textView.setTextColor(color);
+ }
+ });
}
- public void setTextColor(@Nullable ColorStateList colors) {
- for (int i = 0; i < getChildCount(); i++) {
- getPinAt(i).setTextColor(colors);
- }
+ public void setTextColor(@Nullable final ColorStateList colors) {
+ forEach(new Consumer() {
+ @Override
+ public void accept(TextView textView) {
+ textView.setTextColor(colors);
+ }
+ });
}
- public void setTextSize(float size) {
- for (int i = 0; i < getChildCount(); i++) {
- getPinAt(i).setTextSize(size);
- }
+ public void setTextSize(final float size) {
+ forEach(new Consumer() {
+ @Override
+ public void accept(TextView textView) {
+ textView.setTextSize(size);
+ }
+ });
}
- public void setTextSize(int unit, float size) {
- for (int i = 0; i < getChildCount(); i++) {
- getPinAt(i).setTextSize(unit, size);
- }
+ public void setTextSize(final int unit, final float size) {
+ forEach(new Consumer() {
+ @Override
+ public void accept(TextView textView) {
+ textView.setTextSize(unit, size);
+ }
+ });
}
public void setOnPinChangedListener(@Nullable OnPinChangedListener listener) {
@@ -245,8 +254,24 @@ public void setOnStateChangedListener(@Nullable OnStateChangedListener listener)
stateListener = listener;
}
+ private void applyGap() {
+ if (pinGap > 0 && getCount() > 1) {
+ forEach(new Consumer() {
+ @Override
+ public void accept(TextView textView) {
+ ((MarginLayoutParams) textView.getLayoutParams()).setMargins(
+ pinGap / 2,
+ 0,
+ pinGap / 2,
+ 0
+ );
+ }
+ });
+ }
+ }
+
private boolean isPinFilled() {
- for (int i = 0; i < getChildCount(); i++) {
+ for (int i = 0; i < getCount(); i++) {
if (TextUtils.isEmpty(getPinAt(i).getText())) {
return false;
}
@@ -254,6 +279,12 @@ private boolean isPinFilled() {
return true;
}
+ private void forEach(Consumer consumer) {
+ for (int i = 0; i < getCount(); i++) {
+ consumer.accept(getPinAt(i));
+ }
+ }
+
public interface OnPinChangedListener {
void onPinChanged(@NonNull PinView view, @NonNull CharSequence s);