Formatieren Sie die Kreditkartennummer mit Android TextWatcher
1. Credit Card Number Pattern

Card Type The issuing network  | Length Number of allowable digits  | IIN Ranges The card number will always begin with ...  | Spacing Patterns How the digits and spaces are printed on the physical credit cards  | 
Visa (incl. VPay)  | 13-19  | 4  | #### #### #### ####
 (4-4-4-4) Pattern not known for 13-15 and 17-19 digit cards.  | 
Visa Electron  | 16  | 4026, 417500, 4405, 4508, 4844, 4913, 4917  | #### #### #### ####
 (4-4-4-4)  | 
American Express  | 15  | 34, 37  | #### ###### #####
 (4-6-5)  | 
MasterCard  | 16  | 51‑55,
 222100‑272099  | #### #### #### ####
 (4-4-4-4)  | 
Diners Club Carte Blanche  | 14  | 300‑305  | #### ###### ####
 (4-6-4)  | 
Diners Club International  | 14  | 300‑305,
 309, 36, 38‑39  | #### ###### ####
 (4-6-4)  | 
Diners Club United States & Canada  | 16  | 54, 55  | #### #### #### ####
 (4-4-4-4)  | 
Discover  | 16  | 6011,
 622126‑622925, 644‑649, 65  | #### #### #### ####
 (4-4-4-4)  | 
JCB  | 16  | 3528‑3589  | #### #### #### ####
 (4-4-4-4)  | 
UATP  | 15  | 1  | #### ##### ######
 (4-5-6)  | 
Dankort  | 16  | 5019  | #### #### #### ####
 (4-4-4-4)  | 
InterPayment  | 16-19  | 636  | #### #### #### ####
 (4-4-4-4) Pattern not known for 17-19 digit cards.  | 
Maestro  | 12-19  | 500000‑509999,
 560000‑589999, 600000‑699999  | #### #### ##### (4-4-5)
 #### ###### ##### (4-6-5) #### #### #### #### (4-4-4-4) #### #### #### #### ### (4-4-4-4-3) Pattern not known for 12, 14, 17, and 18 digit cards.  | 
China UnionPay  | 16-19  | 62  | #### #### #### #### (4-4-4-4)
 ###### ############# (6-13) Pattern not known for 17-18 digit cards.  | 
2. Example: TextWatcher Credit Card Number
In diesem Beispiel basiert die Klasse CreditCardNumberTextWatcher auf den ersten Zeichen, die der Benutzer in EditText eingibt, um den Typ Credit Card zu ermitteln:

Als nächstes basiert es auf dem Typ Credit Card um die Kartennummer zu formatieren, die der Benutzer eingibt:

Visa Electron Credit Card Type. (####-####-####-####) (4-4-4-4)

UATP Credit Card Type. (####-#####-######) (4-5-6)
OK, Auf Android Studio erstellen Sie ein neues Projekt:
- File > New > New Project > Empty Activity
- Name: TextWatcherCreditCardExample
 - Package name: org.o7planning.textwatchercreditcardexample
 - Language: Java
 
 
Kopieren Sie einige Foto-Dateien in den Ordner drawable vom Projekt:

CreditCardType.java
package org.o7planning.textwatchercreditcardexample;
import java.util.Arrays;
public enum CreditCardType {
    // 4
    VISA("Visa", "icon_visa",
            13, 19,
            new int[]{4},
            new int[]{4,4,4,4,4}
    ),
    // 4026, 417500, 4405, 4508, 4844, 4913, 4917
    VISA_ELECTRON("Visa Electron", "icon_visa_electron",
            16, 16,
            new int[]{4026, 417500, 4405, 4508, 4844, 4913, 4917},
            new int[]{4,4,4,4}
    ),
    // 34, 37
    AMERICAN_EXPRESS("American Express", "icon_american_express",
            15, 15,
            new int[]{34, 37},
            new int[]{4,6,5}
    ),
    // 51‑55, 222100‑272099
    MASTERCARD("MasterCard", "icon_mastercard",
            16, 16,
            concat(intRange(51,55), intRange(222100,272099)),
            new int[]{4,4,4,4}
    ),
    // 6011, 622126‑622925, 644‑649, 65
    DISCOVER("MasterCard", "icon_mastercard",
            16, 16,
            append(concat(intRange(622126,622925), intRange(644,649)),6011,65),
            new int[]{4,4,4,4}
    ),
    // 3528‑3589
    JCB("JCB", "icon_jcb",
            16, 16,
             intRange(3528,3589),
            new int[]{4,4,4,4}
    ),
    // 1
    UATP("UATP", "icon_uatp",
            15, 15,
            new int[]{1},
            new int[]{4,5,6}
    ),
    // 5019
    DANKORT("Dankort", "icon_dankort",
            16, 16,
            new int[]{5019},
            new int[]{4,4,4,4}
    );
    public static final int[] DEFAULT_BLOCK_LENGTHS = new int[] {4, 4, 4, 4, 4};
    public static final int DEFAULT_MAX_LENGTH = 4 * 5 ;
    private String[] prefixs;
    private int[] blockLengths;
    private String name;
    // Name of Image in "drawable" folder.
    private String imageResourceName;
    private int minLength;
    private int maxLength;
    CreditCardType(String name, String imageResourceName,
                    int minLength, int maxLength,
                    int[] intPrefixs, int[] blockLengths)  {
        this.name = name;
        this.imageResourceName = imageResourceName;
        if(intPrefixs!= null)  {
            this.prefixs = new String[intPrefixs.length];
            for(int i=0;i< intPrefixs.length;i++) {
                this.prefixs[i] = String.valueOf(intPrefixs[i]);
            }
        }
        this.minLength = minLength;
        this.maxLength = maxLength;
        this.blockLengths = blockLengths;
    }
    public String getName() {
        return name;
    }
    public int getMinLength() {
        return minLength;
    }
    public int getMaxLength() {
        return maxLength;
    }
    public String[] getPrefixs()  {
        return this.prefixs;
    }
    public int[] getBlockLengths()  {
        return this.blockLengths;
    }
    public String getImageResourceName()  {
        return this.imageResourceName;
    }
    private static int[] intRange(int from, int to)  {
        int length = to - from + 1;
        int[] ret = new int[length];
        for(int i= from; i < to + 1; i++) {
            ret[i-from] = i;
        }
        return ret;
    }
    private static int[] concat(int[] first, int[] second)  {
        int[] both = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, both, first.length, second.length);
        return both;
    }
    private static int[] append(int[] first, int ... value)  {
        if(value == null || value.length == 0)  {
            return first;
        }
        int[] both = Arrays.copyOf(first, first.length + value.length);
        for(int i = 0; i < value.length; i++) {
            both[first.length + i] = value[i];
        }
        return both;
    }
    public static CreditCardType detect(String creditCardNumber)  {
        if(creditCardNumber == null || creditCardNumber.isEmpty())  {
            return null;
        }
        CreditCardType found = null;
        int max = 0;
        for(CreditCardType type: CreditCardType.values()) {
            for(String prefix : type.prefixs) {
                if(creditCardNumber.startsWith(prefix) && prefix.length() > max) {
                    found = type;
                    max = prefix.length();
                }
            }
        }
        return found;
    }
}
CreditCardNumberTextWatcher.java
package org.o7planning.textwatchercreditcardexample;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
public class CreditCardNumberTextWatcher implements TextWatcher {
    private static final String LOG_TAG = "AndroidExample";
    public static final char SEPARATOR = '-';
    private EditText editText;
    private int after;
    private String beforeString;
    public CreditCardNumberTextWatcher(EditText editText) {
        this.editText = editText;
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        this.after = after;
        this.beforeString = s.toString();
        Log.e(LOG_TAG, "@@beforeTextChanged s=" + s
                + " . start="+ start+" . after=" + after+" . count="+ count);
    }
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        Log.e(LOG_TAG, "@@onTextChanged s=" + s
                + " . start="+ start+" . before=" + before+" . count="+ count);
        String newText = s.toString();
        String textPrefix = newText.substring(0, start);
        String textInserted = newText.substring(start, start + this.after);
        String textSuffix = newText.substring(start + this.after);
        String textBeforeCursor = textPrefix + textInserted;
        // User delete the SEPARATOR.
        if(this.after == 0 && count == 0 && beforeString.charAt(start) == SEPARATOR)  {
            if(start > 0)  {
                textPrefix = textPrefix.substring(0, textPrefix.length() -1);
            }
        }
        // Non-digit
        String regex = "[^\\d]";
        String textPrefixClean = textPrefix.replaceAll(regex, "");
        String textInsertedClean = textInserted.replaceAll(regex, "");
        String textSuffixClean = textSuffix.replaceAll(regex, "");
        String textBeforeCursorClean = textPrefixClean + textInsertedClean;
        // creditCardNumber
        String newTextClean = textPrefixClean + textInsertedClean + textSuffixClean;
        CreditCardType creditCardType = this.showDetectedCreditCardImage(newTextClean);
        int[] blockLengths = CreditCardType.DEFAULT_BLOCK_LENGTHS; // {4,4,4,4,4}
        int minLength = 0;
        int maxLength = CreditCardType.DEFAULT_MAX_LENGTH; // 4*5
        if(creditCardType != null)  {
            blockLengths = creditCardType.getBlockLengths();
            minLength = creditCardType.getMinLength();
            maxLength = creditCardType.getMaxLength();
        }
        Log.i(LOG_TAG, "newTextClean= " + newTextClean);
        int[] separatorIndexs = new int[blockLengths.length];
        for(int i=0; i < separatorIndexs.length; i++) {
            if(i==0)  {
                separatorIndexs[i] = blockLengths[i];
            } else {
                separatorIndexs[i] = blockLengths[i] + separatorIndexs[i-1];
            }
        }
        Log.i(LOG_TAG, "blockLengths= " + this.toString(blockLengths));
        Log.i(LOG_TAG, "separatorIndexs= " +  this.toString(separatorIndexs));
        int cursorPosition = start + this.after - textBeforeCursor.length() + textBeforeCursorClean.length();
        StringBuilder sb = new StringBuilder();
        int separatorCount = 0;
        int cursorPositionDelta = 0;
        int LOOP_MAX = Math.min(newTextClean.length(), maxLength);
        for(int i = 0; i < LOOP_MAX; i++) {
            sb.append(newTextClean.charAt(i));
            if(this.contains(separatorIndexs,i + 1) && i < LOOP_MAX - 1) {
                sb.append(SEPARATOR);
                separatorCount++;
                if(i < cursorPosition) {
                    cursorPositionDelta++;
                }
            }
        }
        cursorPosition= cursorPosition + cursorPositionDelta;
        String textFormatted = sb.toString();
        if(cursorPosition > textFormatted.length()) {
            cursorPosition =  textFormatted.length();
        }
        this.editText.removeTextChangedListener(this);
        this.editText.setText(textFormatted);
        this.editText.addTextChangedListener(this);
        this.editText.setSelection(cursorPosition);
    }
    @Override
    public void afterTextChanged(Editable s) {
    }
    private String toString(int[] array)  {
        StringBuilder sb= new StringBuilder();
        for(int i=0;i< array.length;i++) {
            if(i == 0) {
                sb.append("[").append(array[i]);
            } else {
                sb.append(", ").append(array[i]);
            }
        }
        sb.append("]");
        return sb.toString();
    }
    private boolean contains(int[] values, int value)  {
        for(int i=0;i<values.length;i++) {
            if(values[i] == value) {
                return true;
            }
        }
        return false;
    }
    private CreditCardType showDetectedCreditCardImage(String creditCardNumber)  {
        CreditCardType type = CreditCardType.detect(creditCardNumber);
        if(type != null)  {
            Drawable icon = ResourceUtils.getDrawableByName(this.editText.getContext(), type.getImageResourceName());
            this.editText.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null);
        } else {
            Drawable icon = ResourceUtils.getDrawableByName(this.editText.getContext(), "icon_none");
            this.editText.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null);
        }
        return type;
    }
}ResourceUtils.java
package org.o7planning.textwatchercreditcardexample;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
public class ResourceUtils {
    public static Drawable getDrawableByName(Context context, String resourceName)  {
        Resources resources = context.getResources();
        final int resourceId = resources.getIdentifier(resourceName, "drawable",
                context.getPackageName());
        return resources.getDrawable(resourceId);
    }
}Die Interface des Beispiel:

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <TextView
        android:id="@+id/textView81"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginRight="16dp"
        android:text="Enter Your Credit Card Number:"
        android:textSize="20sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <EditText
        android:id="@+id/editText_creditCardNumber"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:drawableRight="@drawable/icon_none"
        android:ems="10"
        android:inputType="phone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView81" />
</androidx.constraintlayout.widget.ConstraintLayout>MainActivity.java
package org.o7planning.textwatchercreditcardexample;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextWatcher;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
    private EditText editTextCreditCardNumber;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.editTextCreditCardNumber = (EditText) this.findViewById(R.id.editText_creditCardNumber);
        TextWatcher textWatcher = new CreditCardNumberTextWatcher(this.editTextCreditCardNumber);
        this.editTextCreditCardNumber.addTextChangedListener(textWatcher);
    }
}Anleitungen Android
- Konfigurieren Sie Android Emulator in Android Studio
 - Die Anleitung zu Android ToggleButton
 - Erstellen Sie einen einfachen File Finder Dialog in Android
 - Die Anleitung zu Android TimePickerDialog
 - Die Anleitung zu Android DatePickerDialog
 - Was ist erforderlich, um mit Android zu beginnen?
 - Installieren Sie Android Studio unter Windows
 - Installieren Sie Intel® HAXM für Android Studio
 - Die Anleitung zu Android AsyncTask
 - Die Anleitung zu Android AsyncTaskLoader
 - Die Anleitung zum Android für den Anfänger - Grundlegende Beispiele
 - Woher weiß man die Telefonnummer von Android Emulator und ändere es
 - Die Anleitung zu Android TextInputLayout
 - Die Anleitung zu Android CardView
 - Die Anleitung zu Android ViewPager2
 - Holen Sie sich die Telefonnummer in Android mit TelephonyManager
 - Die Anleitung zu Android Phone Calls
 - Die Anleitung zu Android Wifi Scanning
 - Die Anleitung zum Android 2D Game für den Anfänger
 - Die Anleitung zu Android DialogFragment
 - Die Anleitung zu Android CharacterPickerDialog
 - Die Anleitung zum Android für den Anfänger - Hello Android
 - Verwenden des Android Device File Explorer
 - Aktivieren Sie USB Debugging auf einem Android-Gerät
 - Die Anleitung zu Android UI Layouts
 - Die Anleitung zu Android SMS
 - Die Anleitung zu Android SQLite Database
 - Die Anleitung zu Google Maps Android API
 - Text zu Sprache in Android
 - Die Anleitung zu Android Space
 - Die Anleitung zu Android Toast
 - Erstellen Sie einen benutzerdefinierten Android Toast
 - Die Anleitung zu Android SnackBar
 - Die Anleitung zu Android TextView
 - Die Anleitung zu Android TextClock
 - Die Anleitung zu Android EditText
 - Die Anleitung zu Android TextWatcher
 - Formatieren Sie die Kreditkartennummer mit Android TextWatcher
 - Die Anleitung zu Android Clipboard
 - Erstellen Sie einen einfachen File Chooser in Android
 - Die Anleitung zu Android AutoCompleteTextView und MultiAutoCompleteTextView
 - Die Anleitung zu Android ImageView
 - Die Anleitung zu Android ImageSwitcher
 - Die Anleitung zu Android ScrollView und HorizontalScrollView
 - Die Anleitung zu Android WebView
 - Die Anleitung zu Android SeekBar
 - Die Anleitung zu Android Dialog
 - Die Anleitung zu Android AlertDialog
 - Die Anleitung zu Android RatingBar
 - Die Anleitung zu Android ProgressBar
 - Die Anleitung zu Android Spinner
 - Die Anleitung zu Android Button
 - Die Anleitung zu Android Switch
 - Die Anleitung zu Android ImageButton
 - Die Anleitung zu Android FloatingActionButton
 - Die Anleitung zu Android CheckBox
 - Die Anleitung zu Android RadioGroup und RadioButton
 - Die Anleitung zu Android Chip und ChipGroup
 - Verwenden Sie Image Asset und Icon Asset von Android Studio
 - Richten Sie die SDCard für den Emulator ein
 - ChipGroup und Chip Entry Beispiel
 - Hinzufügen externer Bibliotheken zu Android Project in Android Studio
 - Wie deaktiviere ich die Berechtigungen, die der Android-Anwendung bereits erteilt wurden?
 - Wie entferne ich Anwendungen aus dem Android Emulator?
 - Die Anleitung zu Android LinearLayout
 - Die Anleitung zu Android TableLayout
 - Die Anleitung zu Android FrameLayout
 - Die Anleitung zu Android QuickContactBadge
 - Die Anleitung zu Android StackView
 - Die Anleitung zu Android Camera
 - Die Anleitung zu Android MediaPlayer
 - Die Anleitung zu Android VideoView
 - Spielen Sie Sound-Effekte in Android mit SoundPool
 - Die Anleitung zu Android Networking
 - Die Anleitung zu Android JSON Parser
 - Die Anleitung zu Android SharedPreferences
 - Die Anleitung zu Android Internal Storage
 - Die Anleitung zu Android External Storage
 - Die Anleitung zu Android Intents
 - Beispiel für eine explizite Android Intent, nennen Sie eine andere Intent
 - Beispiel für implizite Android Intent, Öffnen Sie eine URL, senden Sie eine Email
 - Die Anleitung zu Android Services
 - Die Anleitung zu Android Notifications
 - Die Anleitung zu Android DatePicker
 - Die Anleitung zu Android TimePicker
 - Die Anleitung zu Android Chronometer
 - Die Anleitung zu Android OptionMenu
 - Die Anleitung zu Android ContextMenu
 - Die Anleitung zu Android PopupMenu
 - Die Anleitung zu Android Fragment
 - Die Anleitung zu Android ListView
 - Android ListView mit Checkbox verwenden ArrayAdapter
 - Die Anleitung zu Android GridView
 
                Show More