84 votes

Mettre un texte constant dans un EditText qui ne devrait pas être modifiable - Android

Je veux avoir un texte constant à l'intérieur de editText comme :

http://<here_user_can_write>

L'utilisateur ne doit pas pouvoir supprimer des caractères de " http:// "J'ai fait des recherches à ce sujet et j'ai trouvé ceci :

editText.setFilters(new InputFilter[] {
    new InputFilter() {
        public CharSequence filter(CharSequence src, int start,
            int end, Spanned dst, int dstart, int dend) {
            return src.length() < 1 ? dst.subSequence(dstart, dend) : "";
        }
    }
}); 

mais je ne sais pas s'il restreint l'utilisateur à ne pas supprimer de caractères de du début à la fin limite. Je n'ai pas non plus compris l'utilisation de la classe Spanned.

Un bon choix serait de mettre en place une TextView à l'intérieur EditText mais je ne pense pas que ce soit possible dans Android puisque les deux sont des Vues, est-ce possible ?

2voto

Ankit Beura Points 21

Il s'agit essentiellement d'ajouter le préfixe "+91" au champ de texte de votre numéro de téléphone.

1) Ajouter ce code à la fonction oncreate() de l'activité

@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_up);

   // Write other things......//

   etPhoneNumber.setFilters(new InputFilter[]{getPhoneFilter(),newInputFilter.LengthFilter(13)});

    etPhoneNumber.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                if (etPhoneNumber.getText().toString().isEmpty()) {
                    etPhoneNumber.setText("+91");
                    Selection.setSelection(etPhoneNumber.getText(), etPhoneNumber.getText().length());                    }
            } else {
                if (etPhoneNumber.getText().toString().equalsIgnoreCase("+91")) {
                    etPhoneNumber.setFilters(new InputFilter[]{});
                    etPhoneNumber.setText("");
                    etPhoneNumber.setFilters(new InputFilter[]{getPhoneFilter(),new InputFilter.LengthFilter(13)});

                }
            }
        }
    });
}

2. déclarer une méthode appelée getPhoneFilter()

    private InputFilter getPhoneFilter() {

    Selection.setSelection(etPhoneNumber.getText(), etPhoneNumber.getText().length());

    etPhoneNumber.addTextChangedListener(new TextWatcher() {

        @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.toString().startsWith("+91")){
                if (etPhoneNumber.getFilters() != null && etPhoneNumber.getFilters().length > 0) {
                    etPhoneNumber.setText("+91");
                    Selection.setSelection(etPhoneNumber.getText(), etPhoneNumber.getText().length());
                }
            }
        }
    });

     // Input filter to restrict user to enter only digits..
    InputFilter filter = new InputFilter() {

        public CharSequence filter(CharSequence source, int start, int end,
                                   Spanned dest, int dstart, int dend) {

            for (int i = start; i < end; i++) {

                if (!String.valueOf(getString(R.string.digits_number)).contains(String.valueOf(source.charAt(i)))) {
                    return "";
                }
            }
            return null;
        }
    };
    return filter;
}

3.déclarer "digits_number" dans votre fichier de valeurs

    <string name="digits_number">1234567890+</string>

2voto

Sur la base de @demaksee commentaire. J'ai étendu EditText et surchargé la fonction onSelectionChanged. Ainsi, l'utilisateur ne peut même pas modifier le préfixe. Très simple et utile. Kotlin :

private var prefix : String? = ""

override fun onSelectionChanged(selStart: Int, selEnd: Int) {
    if (prefix != null && prefix!!.isNotBlank()) {
        var finalStart = selStart
        var finalEnd = selEnd

        val prefixLength = prefix!!.length
        if (prefixLength > selStart) {
            finalStart = prefixLength
        }

        if (prefixLength > selEnd) {
            finalEnd = prefixLength
        }

        if (finalStart == selStart && finalEnd == selEnd) {
            super.onSelectionChanged(finalStart, finalEnd)
        } else {
            val startWithPrefix = text?.startsWith(prefix ?: "") ?: prefix.isNullOrBlank()
            if (!startWithPrefix) {
                setText(prefix)
            }

            setSelection(finalStart, finalEnd)
        }
    }
}

public fun setPrefix(prefix: String) {
    editText.setText(prefix)
    editText.setSelection(prefix.length)
    this.prefix = prefix
}

1voto

Veedka Points 366

Voici une solution moins efficace qui devrait permettre de traiter tous les cas où des caractères OU des mots sont supprimés/insérés dans OU autour du préfixe.

prefix = "http://"
extra = "ahhttp://"
differencePrefix(prefix, extra) = "aht"

Code :

public static String differencePrefix(String prefix, String extra) {
    if (extra.length() < prefix.length()) return "";
    StringBuilder sb = new StringBuilder();
    StringBuilder eb = new StringBuilder();
    int p = 0;
    for (int i = 0; i < extra.length(); i++) {
        if (i >= prefix.length()) {
            while(p < extra.length()) {
                eb.append(extra.charAt(p));
                p++;
            }
            break;
        }
        if (p >= extra.length()) break;
        char pchar = extra.charAt(p);
        char ichar = prefix.charAt(i);
        while(pchar != ichar) {
            //check if char was deleted
            int c = i + 1;
            if (c < prefix.length()) {
                char cchar = prefix.charAt(c);
                if (cchar == pchar) {
                    break;
                }
            }
            sb.append(pchar);
            p++;
            if (p >= extra.length()) break;
            pchar = extra.charAt(p);
        }
        p++;
    }

    return eb.toString() + sb.toString();
}

Vous pouvez l'utiliser comme suit

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 s) {
        String input = s.toString();
        if (!input.startsWith(prefix)) {
            String extra = differencePrefix(prefix, input);
            String newInput = prefix + extra;
            editText.setText(newInput);
            editText.setSelection(newInput.length());
        }
    }
});

1voto

Je viens de trouver la solution pour rendre le préfixe non modifiable et pour sauvegarder le texte si vous essayez de supprimer le préfixe. C'est très proche de la réponse de @Rajitha Siriwardena. Tout ce que vous avez oublié, c'est de sauvegarder le texte avant d'appliquer toute modification. Il sera restauré dans afterTextChanged(...).

Code :

final String prefix = "http://";
editText.setText(prefix);
Selection.setSelection(editText.getText(), editText.getText().length());

editText.addTextChangedListener(new TextWatcher() {
    String text;
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        text = charSequence.toString();
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void afterTextChanged(Editable editable) {
        if (!editable.toString().startsWith(prefix)) {
            editText.setText(text);
            Selection.setSelection(editText.getText(), editText.getText().length());
        }
    }
});

1voto

Mr.Nestorjava Points 11
    EditText msg=new EditText(getContext());
                msg.setSingleLine(true);
                msg.setSingleLine();
                msg.setId(View.generateViewId());
                msg.measure(0,0);

                TextView count=new TextView(getContext());
                count.setTextColor(Color.parseColor("#666666"));
                count.setText("20");
                count.setPadding(0,0,(int)Abstract.getDIP(getContext(),10),0);
                count.measure(0,0);
float tenPIX =TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10,getContext().getResources().getDisplayMetrics());

 msg.setPadding((int)tenPIX,(int)tenPIX,(int)(int)tenPIX+count.getMeasuredWidth(),(int)tenPIX);

                RelativeLayout ll1=new RelativeLayout(getContext());
                ll1.addView(msg,new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

LayoutParams countlp=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                countlp.addRule(RelativeLayout.ALIGN_END,msg.getId());
                countlp.addRule(RelativeLayout.ALIGN_BASELINE,msg.getId());
                ll1.addView(count,countlp);

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