web-dev-qa-db-fra.com

EditText OnKeyListener ne fonctionne pas

Je sais cette/question similaire a déjà été posée, mais la solution proposée ne fonctionne pas pour moi, alors je pose à nouveau la question. J'ai essayé la solution proposée dans cette réponse, mais mon OnKeyListener n’est toujours pas invoqué sur certains appareils, en particulier ceux dotés d’un système d’exploitation en stock. J'ai besoin de détecter en appuyant sur la touche Suppr du clavier logiciel quand il n'y a pas de caractère dans editText. Voici mon code;

EditText et = (EditText) findViewById(R.id.et);
    et.setOnKeyListener(new EditText.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            Log.d("OnKeyListener", keyCode + " character(code) to send");
            return false;
        }
    });
9
Ammar

Je me suis enfin résolu en implémentant cette fonctionnalité via TextWatcher. Le principal obstacle était que je devais détecter une presse arrière même quand il n'y avait pas de caractère dans EditText ou du moins que l'utilisateur final s'aperçut qu'il n'y avait pas de caractère ici. Le poing ne pouvait pas être réalisé mais j'ai fait le dernier. Voici la solution détaillée.

Tout d’abord, j’ai toujours gardé un caractère espace '' dans ma editText.

editText.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
        if(cs.toString().length() == 0)
            editText.setText(" ");
    }

    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { }

    @Override
    public void afterTextChanged(Editable arg0) { }

});

Ensuite, j'ai personnalisé EditText pour m'avertir de chaque changement de position du curseur. Cet objectif est atteint en remplaçant la méthode onSelectionChanged par EditText. Ma EditText personnalisée ressemble à ceci.

public class SelectionEnabledEditText extends EditText {
    public SelectionEnabledEditText(Context context) {
        super(context);
    }

    public SelectionEnabledEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SelectionEnabledEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);

        if(onSelectionChangeListener != null)
            onSelectionChangeListener.onSelectionChanged(selStart, selEnd);
    }

    public static interface OnSelectionChangeListener{
        public void onSelectionChanged(int selStart, int selEnd);
    }

    private  OnSelectionChangeListener onSelectionChangeListener;

    public void setOnSelectionChangeListener(OnSelectionChangeListener onSelectionChangeListener) {
        this.onSelectionChangeListener = onSelectionChangeListener;
    }
}

Enfin, dans mon activité, j’écoute l’événement de modification de la position du curseur et je réinitialise la position de celui-ci dans editText s’il existe au début du caractère de caractère requis, c’est-à-dire au 0e index, comme ceci;

editText.setOnSelectionChangeListener(new SelectionEnabledEditText.OnSelectionChangeListener() {
    @Override
    public void onSelectionChanged(int selStart, int selEnd) {
        if (selEnd == 0) {
            if (editText.getText().toString().length() == 0)
                editText.setText(" ");

            editText.setSelection(1);
        }
    }
});

J'espère que cela serait utile dans des situations similaires. Les suggestions sont les bienvenues pour des améliorations/optimisations.

18
Ammar

La documentation indique que les événements de clé ne seront propagés que pour les frappes de clé matérielles, pas les logiciels.

http://developer.Android.com/reference/Android/view/View.OnKeyListener.html

Les fabricants de périphériques sont en fait découragés de propager des événements de clavier logiciel par le biais d'auditeurs clés, bien qu'il incombe au fabricant de le respecter ou de traiter les claviers logiciel et dur avec la même égalité.

À partir d'Android 4.2.2, le système Android lui-même ne prend plus en charge les événements Stoke pour les claviers logiciels, de sorte que même les fabricants ne pourront pas choisir leur voie.

La seule option infaillible consiste donc à mettre en œuvre votre propre IME (clavier logiciel) et à gérer vous-même les frappes au clavier.

TextWatcher peut être utilisé principalement pour remplacer les principaux écouteurs, cependant editText.setText (...); déclenchera également les événements TextWatcher, donc si vous êtes intéressé par les touches tapées, TextWatcher n’est probablement pas une solution non plus.

Soyez prudent lorsque vous utilisez TextWatcher avec AutocomleteTextView ou EditText. Ne modifiez pas le texte du contenu d'AutocompleteTextView/EditText à partir d'événements TextWatcher, sinon vous vous retrouverez probablement dans une boucle infinie d'événement/écoute.

10
Ameer

Sur la base de documentation de OnKeyListener, il semble que le rappel n’est appelé que pour les claviers matériels.

Définition d'interface pour un rappel à invoquer lorsqu'un événement de clé matérielle est distribué à cette vue. Le rappel sera appelé avant que l'événement de clé ne soit attribué à la vue. Ceci n'est utile que pour les claviers matériels; une méthode de saisie logicielle n’a aucune obligation de déclencher cet écouteur.

2
Nirekin

Il y a un attribut pour EditText: Android:imeOptions

<androidx.appcompat.widget.AppCompatEditText
    Android:id="@+id/main_editor"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:imeOptions="actionGo"
    />

J'ai remarqué que pour les valeurs: actionGo, actionNone, normal, actionSearch onKeyListener a été appelée.

P.S. Cela a même fonctionné sans spécifier cet attribut. 

0
rehman_00001