diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 97626ba..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index fbb6828..7158618 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,10 +37,26 @@ - + + + + + + 1.8 + + + + + + + \ No newline at end of file diff --git a/EditCard/src/main/java/morxander/editcard/CardNumberTransformationMethod.java b/EditCard/src/main/java/morxander/editcard/CardNumberTransformationMethod.java new file mode 100644 index 0000000..f931780 --- /dev/null +++ b/EditCard/src/main/java/morxander/editcard/CardNumberTransformationMethod.java @@ -0,0 +1,67 @@ +package morxander.editcard; + +import android.text.method.PasswordTransformationMethod; +import android.view.View; + +/** + * Created by Mac on 2017. 1. 25. PM 1:56 + * make password bullet + */ + +public class CardNumberTransformationMethod extends PasswordTransformationMethod { + final static int NORMAL = 0; + final static int AMERICAN_EXPRESS = 1; + final static int DINERS_CLUB = 2; + + // Card type + private int type = 0; + + private static CardNumberTransformationMethod ourInstance = new CardNumberTransformationMethod(); + + public static CardNumberTransformationMethod getInstance() { + return ourInstance; + } + + public void setType(int type) { + this.type = type; + } + + @Override + public CharSequence getTransformation(CharSequence source, View view) { + return new CardNumberCharSequence(source); + } + + private class CardNumberCharSequence implements CharSequence { + private CharSequence mSource; + + public CardNumberCharSequence(CharSequence source) { + mSource = source; // Store char sequence + } + + public char charAt(int index) { + switch(type) { + case AMERICAN_EXPRESS: + case DINERS_CLUB: + if (index < 11 && index > 4) { + return '*'; + } + break; + default: + if (index > 9 && index < 14) { + return '*'; + } + break; + } + return mSource.charAt(index); + } + + public int length() { + return mSource.length(); + } + + public CharSequence subSequence(int start, int end) { + CharSequence charSequence = mSource.subSequence(start, end); + return charSequence; // Return default + } + } +} diff --git a/EditCard/src/main/java/morxander/editcard/CardPattern.java b/EditCard/src/main/java/morxander/editcard/CardPattern.java index 31fc2df..9e7c645 100644 --- a/EditCard/src/main/java/morxander/editcard/CardPattern.java +++ b/EditCard/src/main/java/morxander/editcard/CardPattern.java @@ -7,32 +7,35 @@ public class CardPattern { // VISA - public static final String VISA = "4[0-9]{12}(?:[0-9]{3})?"; - public static final String VISA_VALID = "^4[0-9]{12}(?:[0-9]{3})?$"; + public static final String VISA = "4[0-9]{0,15}"; // TODO: 2017. 1. 25. Check this. + public static final String VISA_VALID = "^4[0-9]{12}(?:[0-9]{3})?$"; // MasterCard - public static final String MASTERCARD = "^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$"; - public static final String MASTERCARD_SHORT = "^(?:222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)"; - public static final String MASTERCARD_SHORTER = "^(?:5[1-5])"; - public static final String MASTERCARD_VALID = "^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$"; + public static final String MASTERCARD = "^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$"; + public static final String MASTERCARD_SHORT = "^(?:222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)"; + public static final String MASTERCARD_SHORTER = "^5[1-5][0-9]{0,14}$"; // TODO: 2017. 1. 25. Check this. + public static final String MASTERCARD_VALID = "^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$"; // American Express - public static final String AMERICAN_EXPRESS = "^3[47][0-9]{0,13}"; - public static final String AMERICAN_EXPRESS_VALID = "^3[47][0-9]{13}$"; + public static final String AMERICAN_EXPRESS = "^3[47][0-9]{0,13}"; + public static final String AMERICAN_EXPRESS_VALID = "^3[47][0-9]{13}$"; // DISCOVER - public static final String DISCOVER = "^6(?:011|5[0-9]{1,2})[0-9]{0,12}"; - public static final String DISCOVER_SHORT = "^6(?:011|5)"; - public static final String DISCOVER_VALID = "^6(?:011|5[0-9]{2})[0-9]{12}$"; + public static final String DISCOVER = "^6(?:011|5[0-9]{1,2})[0-9]{0,12}"; + public static final String DISCOVER_SHORT = "^6(?:011|5)"; + public static final String DISCOVER_VALID = "^6(?:011|5[0-9]{2})[0-9]{12}$"; // JCB - public static final String JCB = "^(?:2131|1800|35\\d{0,3})\\d{0,11}$"; - public static final String JCB_SHORT = "^2131|1800"; - public static final String JCB_VALID = "^(?:2131|1800|35\\d{3})\\d{11}$"; + public static final String JCB = "^(?:2131|1800|35\\d{0,3})\\d{0,11}$"; + public static final String JCB_SHORT = "^(2131|1800|35)[0-9]{0,14}$"; // TODO: 2017. 1. 25. Check this. + public static final String JCB_VALID = "^(?:2131|1800|35\\d{3})\\d{11}$"; // Discover - public static final String DINERS_CLUB = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"; - public static final String DINERS_CLUB_SHORT = "^30[0-5]"; - public static final String DINERS_CLUB_VALID = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"; + public static final String DINERS_CLUB = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"; + public static final String DINERS_CLUB_SHORT = "^3(0[0-5]|095|[689])[0-9]{0,12}"; // TODO: 2017. 1. 25. Check this. + public static final String DINERS_CLUB_VALID = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$"; + + // Union 2017.01.25 + public static final String UNION_PAY_SHORT = "62[0-9]{0,14}"; // TODO: 2017. 1. 25. Check this. } diff --git a/EditCard/src/main/java/morxander/editcard/EditCard.java b/EditCard/src/main/java/morxander/editcard/EditCard.java index aca43ab..c2a85c6 100644 --- a/EditCard/src/main/java/morxander/editcard/EditCard.java +++ b/EditCard/src/main/java/morxander/editcard/EditCard.java @@ -7,18 +7,24 @@ import android.text.InputFilter; import android.text.Spanned; import android.text.TextWatcher; +import android.text.method.TransformationMethod; import android.util.AttributeSet; import android.widget.EditText; import java.util.regex.Pattern; +import static android.R.attr.start; + /** - * Created by morxander on 11/19/16. + * Created by Mac on 11/19/16 PM 2:24 */ public class EditCard extends EditText { - String type = "UNKNOWN"; + private String type = ""; + public CardNumberTransformationMethod cardNumberTransformationMethod; + // 2017.01.25 + public TextWatcher textWatcher; public EditCard(Context context) { super(context); @@ -44,35 +50,79 @@ public EditCard(Context context, AttributeSet attrs, int defStyleAttr, int defSt private void addMagic() { // Changing the icon when it's empty changeIcon(); + + cardNumberTransformationMethod = CardNumberTransformationMethod.getInstance(); + setTransformationMethod(cardNumberTransformationMethod); + // Adding the TextWatcher addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { - + if (textWatcher != null) textWatcher.beforeTextChanged(s, start,count, after); } @Override public void onTextChanged(CharSequence s, int position, int before, int action) { - if (action == 1) { - if (type.equals("UNKNOWN") || type.equals("Visa") || type.equals("Discover") || type.equals("JCB")) { - if (position == 3 || position == 8 || position == 13) { - if (!s.toString().endsWith("-")) { - append("-"); + changeIcon(s.toString()); + + boolean isChaged = false; + String text = getText().toString(); + String onlyNum = getText().toString().replaceAll("-", ""); + + StringBuilder stringBuilder = new StringBuilder(onlyNum); + + if (type.equals("UNKNOWN") || type.equals("MasterCard") || type.equals("Visa") || type.equals("Discover") || type.equals("JCB")|| type.equals("Union_Pay")) { + if (text.length() > 4) { + if ('-' != text.charAt(4)) { + isChaged = true; + } + stringBuilder.insert(4, "-"); + if (text.length() > 9) { + if ('-' != text.charAt(9)) { + isChaged = true; + } + stringBuilder.insert(9, "-"); + if (text.length() > 14) { + if ('-' != text.charAt(14)) { + isChaged = true; + } + stringBuilder.insert(14, "-"); } } - } else if (type.equals("American_Express") || type.equals("Diners_Club")) { - if (position == 3 || position == 10) { - if (!s.toString().endsWith("-")) { - append("-"); + } + setFilters(new InputFilter[]{new InputFilter.LengthFilter(19)}); + cardNumberTransformationMethod.setType(CardNumberTransformationMethod.NORMAL); + } else if (type.equals("American_Express") || type.equals("Diners_Club")) { + if (type.equals("Diners_Club")) { + setFilters(new InputFilter[]{new InputFilter.LengthFilter(16)}); + cardNumberTransformationMethod.setType(CardNumberTransformationMethod.DINERS_CLUB); + }else { + setFilters(new InputFilter[]{new InputFilter.LengthFilter(17)}); + cardNumberTransformationMethod.setType(CardNumberTransformationMethod.AMERICAN_EXPRESS); + } + if (text.length() > 4) { + if ('-' != text.charAt(4)) { + isChaged = true; + } + stringBuilder.insert(4, "-"); + if (text.length() > 11) { + if ('-' != text.charAt(11)) { + isChaged = true; } + stringBuilder.insert(11, "-"); } } } + if (isChaged) { + setText(stringBuilder.toString()); + }else{ + setSelection(length()); + } } @Override public void afterTextChanged(Editable editable) { - changeIcon(); + if (textWatcher != null) textWatcher.afterTextChanged(editable); } }); // The input filters @@ -92,11 +142,17 @@ public CharSequence filter(CharSequence source, int start, int end, Spanned dest } private void changeIcon() { - String s = getText().toString().replace("-", "").trim(); + String s = getText().toString(); + changeIcon(s); + } + + // 2017.01.25 + private void changeIcon(String s) { + s = s.replaceAll("-", "").trim(); if (s.startsWith("4") || s.matches(CardPattern.VISA)) { setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.vi, 0); type = "Visa"; - } else if (s.matches(CardPattern.MASTERCARD_SHORTER) || s.matches(CardPattern.MASTERCARD_SHORT) || s.matches(CardPattern.MASTERCARD)) { + } else if (s.matches(CardPattern.MASTERCARD_SHORTER)) { setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.mc, 0); type = "MasterCard"; } else if (s.matches(CardPattern.AMERICAN_EXPRESS)) { @@ -105,12 +161,15 @@ private void changeIcon() { } else if (s.matches(CardPattern.DISCOVER_SHORT) || s.matches(CardPattern.DISCOVER)) { setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ds, 0); type = "Discover"; - } else if (s.matches(CardPattern.JCB_SHORT) || s.matches(CardPattern.JCB)) { + } else if (s.matches(CardPattern.JCB_SHORT)) { setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.jcb, 0); type = "JCB"; - } else if (s.matches(CardPattern.DINERS_CLUB_SHORT) || s.matches(CardPattern.DINERS_CLUB)) { + } else if (s.matches(CardPattern.DINERS_CLUB_SHORT)) { setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.dc, 0); type = "Diners_Club"; + } else if (s.matches(CardPattern.UNION_PAY_SHORT)) { + setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.un, 0); + type = "Union_Pay"; } else { setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.card, 0); type = "UNKNOWN"; @@ -128,10 +187,29 @@ public boolean isValid() { if (getCardNumber().matches(CardPattern.DISCOVER_VALID)) return true; if (getCardNumber().matches(CardPattern.DINERS_CLUB_VALID)) return true; if (getCardNumber().matches(CardPattern.JCB_VALID)) return true; + // TODO: 2017. 1. 25. Need to add union-pay valid check return false; } - + // 2017.01.25 public String getCardType(){ return type; } + + // 2017.01.25 + public void addCardTextChangedListener(TextWatcher textWatcher) { + this.textWatcher = textWatcher; + } + + // 2017.01.25 + public void removeCardNumberTransformationMethod(TransformationMethod method) { + setTransformationMethod(null); + } + + // 2017.01.25 + public void setCardNumberTransformationMethod(TransformationMethod method) { + if (cardNumberTransformationMethod == null) { + cardNumberTransformationMethod = CardNumberTransformationMethod.getInstance(); + } + setTransformationMethod(cardNumberTransformationMethod); + } } diff --git a/EditCard/src/main/res/drawable/un.png b/EditCard/src/main/res/drawable/un.png new file mode 100644 index 0000000..fa5d67f Binary files /dev/null and b/EditCard/src/main/res/drawable/un.png differ diff --git a/README.MD b/README.MD index d1b20d5..9cdeef9 100644 --- a/README.MD +++ b/README.MD @@ -38,6 +38,7 @@ For now we only support the following card types : * DISCOVER * JCB * Discover +* Union ### License GNU GENERAL PUBLIC LICENSE 3 diff --git a/gradle.properties b/gradle.properties index a110a05..d8498da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,8 +9,6 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -org.gradle.java.home=/usr/lib/jvm/java-1.8.0-openjdk-amd64 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects