24 votes

Format personnalisé de saisie de texte Android pour accepter le numéro de carte de crédit

Comment faire pour que l'édition de texte accepte l'entrée dans le format

4digitnumber-4dignumber-4dignumber-4dignumber   

Le code

text.addTextChangedListener(new TextWatcher() {
    int len = 0;
    String string ;
    @Override

    public void afterTextChanged(Editable s) {

        text.setOnKeyListener(new OnKeyListener()
        {   public boolean onKey(View v, int keyCode, KeyEvent event)
            {              
                    if (keyCode == KeyEvent.KEYCODE_DEL)
                    {

                    }
                    else{

                        string = text.getText().toString();
                        len = string.length()+1;
                        if(len%5==0){text.append("-");}

             }

                return false;      }   });
    }
});

fonctionne bien lors de l'ajout, mais la suppression ou la modification pose problème.

26voto

noone Points 658

Maintenant, cela fonctionne bien pour le clavier souple/dur pour toutes les opérations de suppression/édition. tx 4 ur help

package com.and;

import android.app.Activity;
import android.app.AlertDialog;
import android.inputmethodservice.KeyboardView;
import android.os.Bundle;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextWatcher;
import android.text.format.Formatter;
import android.text.method.NumberKeyListener;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.Toast;

public class ccformat extends Activity {

    String a;
    int keyDel;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final EditText text = (EditText) findViewById(com.and.R.id.editText1);

        text.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                boolean flag = true;
                String eachBlock[] = text.getText().toString().split("-");
                for (int i = 0; i < eachBlock.length; i++) {
                    if (eachBlock[i].length() > 4) {
                        flag = false;
                    }
                }
                if (flag) {

                    text.setOnKeyListener(new OnKeyListener() {

                        @Override
                        public boolean onKey(View v, int keyCode, KeyEvent event) {

                            if (keyCode == KeyEvent.KEYCODE_DEL)
                                keyDel = 1;
                            return false;
                        }
                    });

                    if (keyDel == 0) {

                        if (((text.getText().length() + 1) % 5) == 0) {

                            if (text.getText().toString().split("-").length <= 3) {
                                text.setText(text.getText() + "-");
                                text.setSelection(text.getText().length());
                            }
                        }
                        a = text.getText().toString();
                    } else {
                        a = text.getText().toString();
                        keyDel = 0;
                    }

                } else {
                    text.setText(a);
                }

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });
    }
}

21voto

MarvinLabs Points 13401

Ça marche :

public class EditTextSample extends Activity {
    // This regexp has to be improved, it does not detect case where you have
    // more than 4 digits in a middle group like: 1234-12345-123
    static final Pattern CODE_PATTERN = Pattern.compile("([0-9]{0,4})|([0-9]{4}-)+|([0-9]{4}-[0-9]{0,4})+");

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.edit_text_sample);

        final EditText editText = (EditText) findViewById(R.id.input);
        editText.addTextChangedListener(new TextWatcher() {

            @Override
            public void afterTextChanged(Editable s) {
                Log.w("", "input" + s.toString());

                if (s.length() > 0 && !CODE_PATTERN.matcher(s).matches()) {
                    String input = s.toString();
                    String numbersOnly = keepNumbersOnly(input);
                    String code = formatNumbersAsCode(numbersOnly);

                    Log.w("", "numbersOnly" + numbersOnly);
                    Log.w("", "code" + code);

                    editText.removeTextChangedListener(this);
                    editText.setText(code);
                    // You could also remember the previous position of the cursor
                    editText.setSelection(code.length());
                    editText.addTextChangedListener(this);
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            private String keepNumbersOnly(CharSequence s) {
                return s.toString().replaceAll("[^0-9]", ""); // Should of course be more robust
            }

            private String formatNumbersAsCode(CharSequence s) {
                int groupDigits = 0;
                String tmp = "";
                for (int i = 0; i < s.length(); ++i) {
                    tmp += s.charAt(i);
                    ++groupDigits;
                    if (groupDigits == 4) {
                        tmp += "-";
                        groupDigits = 0;
                    }
                }
                return tmp;
            }
        });
    }
}

7voto

Roberto Leinardi Points 1577

Si vous voulez juste le groupe visuellement les nombres, mais vous ne voulez pas modifier la valeur de la EditText en ajoutant des tirets, vous pouvez utiliser ceci Span approche :

EditText editText = findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable editable) {
        Object[] paddingSpans = editable.getSpans(0, editable.length(), DashSpan.class);
        for (Object span : paddingSpans) {
            editable.removeSpan(span);
        }

        addSpans(editable);
    }

    private static final int GROUP_SIZE = 4;

    private void addSpans(Editable editable) {

        final int length = editable.length();
        for (int i = 1; i * (GROUP_SIZE) < length; i++) {
            int index = i * GROUP_SIZE;
            editable.setSpan(new DashSpan(), index - 1, index,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
    }
});

où le DashSpan ressemble à ceci :

/**
 * A {@link ReplacementSpan} used for spacing in {@link android.widget.EditText}
 * to space things out. Adds '-'s
 */
public class DashSpan extends ReplacementSpan {

    @Override
    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
        float padding = paint.measureText("-", 0, 1);
        float textSize = paint.measureText(text, start, end);
        return (int) (padding + textSize);
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
                     int bottom, @NonNull Paint paint) {
        canvas.drawText(text.subSequence(start, end) + "-", x, y, paint);
    }
}

De cette façon, vous aurez visuellement le regroupement à l'aide des tirets, mais les getText() retournera le texte sans aucun regroupement.

Pour forcer uniquement les nombres, vous pouvez ajouter les attributs android:digits="0123456789" et android:inputType="number" à la EditText .

Cette solution est basée sur le code de este bibliothèque.

3voto

Hiren Patel Points 15583

Dans mon cas, le code ci-dessous fonctionne bien.

editTextCreditCard.addTextChangedListener(new FourDigitCardFormatWatcher());

Ajouter une classe personnalisée pour TextWatcher .

public class FourDigitCardFormatWatcher implements TextWatcher {

        private static final char space = ' ';

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            if (s.length() > 0 && (s.length() % 5) == 0) {
                final char c = s.charAt(s.length() - 1);
                if (space == c) {
                    s.delete(s.length() - 1, s.length());
                }
            }
            if (s.length() > 0 && (s.length() % 5) == 0) {
                char c = s.charAt(s.length() - 1);
                if (Character.isDigit(c) && TextUtils.split(s.toString(), String.valueOf(space)).length <= 3) {
                    s.insert(s.length() - 1, String.valueOf(space));
                }
            }
        }
    }

J'espère que cela vous aidera.

1voto

AndroidDev Points 74

Cela fonctionne dans tous les cas, lorsque vous insérez ou supprimez un caractère, le format sera toujours correct. Assurez-vous de définir

android:inputType="number"

/

myEditText.addTextChangedListener(new TextWatcher() {
        private final String space = "-"; // you can change this to whatever you want
        private final Pattern pattern = Pattern.compile("^(\\d{4}"+space+"{1}){0,3}\\d{1,4}$"); // check whether we need to modify or not
        @Override
        public void onTextChanged(CharSequence s, int st, int be, int count) {
            String currentText = myEditText.getText().toString();
            if (currentText.isEmpty() || pattern.matcher(currentText).matches())
                return; // no need to modify
            String numbersOnly = currentText.trim().replaceAll("[^\\d.]", "");; // remove everything but numbers
            String formatted = "";
            for(int i = 0; i < numbersOnly.length(); i += 4)
                if (i + 4 < numbersOnly.length())
                    formatted += numbersOnly.substring(i,i+4)+space;
                else
                    formatted += numbersOnly.substring(i);
            myEditText.setText(formatted);
            myEditText.setSelection(myEditText.getText().toString().length());
        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        @Override
        public void afterTextChanged(Editable e) {}
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X