web-dev-qa-db-fra.com

Android - Gère "Entrée" dans un EditText

Je me demande s’il existe un moyen de gérer l’utilisateur en appuyant sur Enter en tapant un EditText, quelque chose comme l'événement HTML onSubmit.

Nous nous demandons également s’il existe un moyen de manipuler le clavier virtuel de manière à ce que le bouton "Terminé" soit étiqueté autrement (par exemple, "Go") et effectue une certaine action lorsque vous cliquez dessus (à nouveau, comme onSubmit).

426
Felix

Je me demande s’il existe un moyen de gérer l’utilisateur en appuyant sur Enter lors de la saisie d'un EditText, quelque chose comme l'événement HTML onSubmit.

Oui.

Nous nous demandons également s’il existe un moyen de manipuler le clavier virtuel de manière à ce que le bouton "Terminé" soit étiqueté autrement (par exemple, "Go") et effectue une certaine action lorsque vous cliquez dessus (à nouveau, comme onSubmit).

Aussi oui.

Vous voudrez regarder les attributs Android:imeActionId et Android:imeOptions , plus la méthode setOnEditorActionListener() , tous sur TextView.

Pour changer le texte du bouton "Terminé" en une chaîne personnalisée, utilisez:

_mEditText.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER);
_
355
CommonsWare
final EditText edittext = (EditText) findViewById(R.id.edittext);
edittext.setOnKeyListener(new OnKeyListener() {
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        // If the event is a key-down event on the "enter" button
        if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
            (keyCode == KeyEvent.KEYCODE_ENTER)) {
          // Perform action on key press
          Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
          return true;
        }
        return false;
    }
});
240
Jarod DY Law

Voici ce que vous faites. Il est également masqué dans le Android exemple de code du développeur 'Bluetooth Chat'. Remplacez les parties en gras indiquant "exemple" par vos propres variables et méthodes.

Commencez par importer ce dont vous avez besoin dans l’activité principale où vous souhaitez que le bouton de retour fasse quelque chose de spécial:

import Android.view.inputmethod.EditorInfo;
import Android.widget.TextView;
import Android.view.KeyEvent;

Maintenant, créez une variable de type TextView.OnEditorActionListener pour votre clé de retour (ici j'utilise exampleListener);

TextView.OnEditorActionListener exampleListener = new TextView.OnEditorActionListener(){

Ensuite, vous devez dire à l'auditeur deux choses à propos de ce qu'il faut faire lorsque vous appuyez sur le bouton de retour. Il doit savoir de quoi EditText nous parlons (ici, j'utilise exampleView), puis il a besoin de savoir quoi faire lorsque la touche Entrée est enfoncée (ici, exemple_confirm ()). S'il s'agit du dernier ou du seul EditText de votre activité, il devrait faire la même chose que la méthode onClick pour votre bouton Soumettre (ou OK, Confirmer, Envoyer, Enregistrer, etc.).

public boolean onEditorAction(TextView exampleView, int actionId, KeyEvent event) {
   if (actionId == EditorInfo.IME_NULL  
      && event.getAction() == KeyEvent.ACTION_DOWN) { 
      example_confirm();//match this behavior to your 'Send' (or Confirm) button
   }
   return true;
}

Enfin, définissez le programme d'écoute (probablement dans votre méthode onCreate);

exampleView.setOnEditorActionListener(exampleListener);
211
Chad Hedgcock

Les claviers matériels génèrent toujours des événements entrants, mais les claviers logiciels renvoient des actionsID et des null différents dans singleLine EditTexts. Ce code répond chaque fois que l'utilisateur appuie sur entrer dans un EditText pour lequel cet écouteur a été défini, indépendamment du type EditText ou du clavier.

import Android.view.inputmethod.EditorInfo;
import Android.view.KeyEvent;
import Android.widget.TextView.OnEditorActionListener;

listener=new TextView.OnEditorActionListener() {
  @Override
  public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
    if (event==null) {
      if (actionId==EditorInfo.IME_ACTION_DONE);
      // Capture soft enters in a singleLine EditText that is the last EditText.
      else if (actionId==EditorInfo.IME_ACTION_NEXT);
      // Capture soft enters in other singleLine EditTexts
      else return false;  // Let system handle all other null KeyEvents
    }
    else if (actionId==EditorInfo.IME_NULL) { 
    // Capture most soft enters in multi-line EditTexts and all hard enters.
    // They supply a zero actionId and a valid KeyEvent rather than
    // a non-zero actionId and a null event like the previous cases.
      if (event.getAction()==KeyEvent.ACTION_DOWN); 
      // We capture the event when key is first pressed.
      else  return true;   // We consume the event when the key is released.  
    }
    else  return false; 
    // We let the system handle it when the listener
    // is triggered by something that wasn't an enter.


    // Code from this point on will execute whenever the user
    // presses enter in an attached view, regardless of position, 
    // keyboard, or singleLine status.

    if (view==multiLineEditText)  multiLineEditText.setText("You pressed enter");
    if (view==singleLineEditText)  singleLineEditText.setText("You pressed next");
    if (view==lastSingleLineEditText)  lastSingleLineEditText.setText("You pressed done");
    return true;   // Consume the event
  }
};

L'apparence par défaut de la touche Entrée dans singleLine = false donne une flèche courbée au clavier. Lorsque singleLine = true dans le dernier EditText, la clé indique DONE, et sur les EditTexts avant, elle indique NEXT. Par défaut, ce comportement est cohérent sur tous les émulateurs Vanilla, Android et Google. L'attribut scrollHorizontal ne fait aucune différence. Le test null est important car la réponse des téléphones aux entrées logicielles est laissée au fabricant. Même dans les émulateurs, les émulateurs Vanilla Level 16 répondent aux entrées logicielles longues en plusieurs lignes et scrollHorizontal EditTexts avec une actionId de NEXT et une valeur null. l'événement.

34
earlcasper

Je sais que cela fait un an, mais je viens de découvrir que cela fonctionne parfaitement pour un EditText.

EditText textin = (EditText) findViewById(R.id.editText1);
textin.setInputType(InputType.TYPE_CLASS_TEXT);

Il empêche tout sauf le texte et l'espace. Je ne pouvais pas tabuler, "retourner" ("\ n") ou quoi que ce soit.

21
Newbie

Cette page décrit exactement comment faire cela.

https://developer.Android.com/training/keyboard-input/style.html

Définissez le Android: imeOptions alors il vous suffit de vérifier le actionId dans onEditorAction. Ainsi, si vous définissez imeOptions sur 'actionDone', vous devez alors rechercher 'actionId == EditorInfo.IME_ACTION_DONE' dans onEditorAction. Assurez-vous également de définir Android: inputType.

Voici le EditText de l'exemple lié ci-dessus:

<EditText
    Android:id="@+id/search"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:hint="@string/search_hint"
    Android:inputType="text"
    Android:imeOptions="actionSend" />

Vous pouvez également définir ceci par programme en utilisant la fonction setImeOptions (int) . Voici le OnEditorActionListener de l'exemple lié ci-dessus:

EditText editText = (EditText) findViewById(R.id.search);
editText.setOnEditorActionListener(new OnEditorActionListener() {
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        boolean handled = false;
        if (actionId == EditorInfo.IME_ACTION_SEND) {
            sendMessage();
            handled = true;
        }
        return handled;
    }
});
20
Mike

Tout comme un addendum à la réponse de Chad (qui fonctionnait presque parfaitement pour moi), j'ai constaté que je devais ajouter un contrôle sur le type d'action KeyEvent pour empêcher mon code de s'exécuter deux fois (une fois sur la touche supérieure et une autre sur la touche inférieure). un événement).

if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_DOWN)
{
    // your code here
}

Voir http://developer.Android.com/reference/Android/view/KeyEvent.html pour plus d'informations sur les événements d'action récurrents (en maintenant la touche Entrée), etc.

16
kermitology

J'ai eu un but similaire. Je voulais résoudre en appuyant sur la touche "Entrée" du clavier (que je voulais personnaliser) dans un AutoCompleteTextView qui étend TextView. J'ai essayé différentes solutions venant d'en haut et elles semblaient fonctionner. MAIS j’ai rencontré quelques problèmes lorsque j’ai commuté le type d’entrée de mon appareil (Nexus 4 avec AOKP ROM) de SwiftKey 3 (où cela fonctionnait parfaitement) sur le clavier standard Android (où, au lieu de gérer le code du écouteur, une nouvelle ligne a été entrée après avoir appuyé sur la touche "Entrée". Il m'a fallu un certain temps pour gérer ce problème, mais je ne sais pas si cela fonctionnera dans toutes les circonstances, quel que soit le type d'entrée utilisé.

Alors voici ma solution:

Définissez l’attribut de type d’entrée du TextView dans le fichier xml sur "text":

Android:inputType="text"

Personnalisez le libellé de la touche "Entrée" du clavier:

myTextView.setImeActionLabel("Custom text", KeyEvent.KEYCODE_ENTER);

Définissez OnEditorActionListener sur TextView:

myTextView.setOnEditorActionListener(new OnEditorActionListener()
{
    @Override
    public boolean onEditorAction(TextView v, int actionId,
        KeyEvent event)
    {
    boolean handled = false;
    if (event.getAction() == KeyEvent.KEYCODE_ENTER)
    {
        // Handle pressing "Enter" key here

        handled = true;
    }
    return handled;
    }
});

J'espère que cela pourra aider les autres à éviter les problèmes que j'ai rencontrés, car ils m'ont presque rendu fou.

16
kaolick

Dans votre XML, ajoutez l'attribut imeOptions à editText

<EditText
    Android:id="@+id/edittext_additem"
    ...
    Android:imeOptions="actionDone"
    />

Ensuite, dans votre code Java, ajoutez OnEditorActionListener au même EditText.

mAddItemEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if(actionId == EditorInfo.IME_ACTION_DONE){
                //do stuff
                return true;
            }
            return false;
        }
    });

Voici l'explication. Les imeOptions = actionDone assigneront "actionDone" à la touche EnterKey. La touche EnterKey du clavier passera de "Enter" à "Done". Ainsi, lorsque vous appuyez sur la touche Entrée, cette action est déclenchée et vous la gérez.

13
Akshayraj Kore

Vous pouvez aussi le faire ..

editText.setOnKeyListener(new OnKeyListener() {

            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event)
            {
                if (event.getAction() == KeyEvent.ACTION_DOWN
                        && event.getKeyCode() ==       KeyEvent.KEYCODE_ENTER) 
                {
                    Log.i("event", "captured");

                    return false;
                } 

            return false;
        }
    });
8
Xar E Ahmer
     password.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if(event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
                submit.performClick();
                return true;
            }
            return false;
        }
    });

Fonctionne très bien pour moi
En plus cacher le clavier

6
V. Kalyuzhnyu

fonctionne parfaitement

public class MainActivity extends AppCompatActivity {  
TextView t;
Button b;
EditText e;

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

    b = (Button) findViewById(R.id.b);
    e = (EditText) findViewById(R.id.e);

    e.addTextChangedListener(new TextWatcher() {

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

            if (before == 0 && count == 1 && s.charAt(start) == '\n') {

                b.performClick();
                e.getText().replace(start, start + 1, ""); //remove the <enter>
            }

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

    b.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            b.setText("ok");

        }
    });
}

}

fonctionne parfaitement

5
Domi mtz

Tout d’abord, vous devez définir EditText listen to key press

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

    // Set the EditText listens to key press
    EditText edittextproductnumber = (EditText) findViewById(R.id.editTextproductnumber);
    edittextproductnumber.setOnKeyListener(this);

}

Deuxièmement, définissez l'événement lors de la pression sur la touche, par exemple, événement pour définir le texte de TextView:

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
    // TODO Auto-generated method stub

 // Listen to "Enter" key press
 if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER))
 {
     TextView textviewmessage = (TextView) findViewById(R.id.textViewmessage);
     textviewmessage.setText("You hit 'Enter' key");
     return true;
 }

return false;   

}

Et enfin, n'oubliez pas d'importer EditText, TextView, OnKeyListener, KeyEvent en haut:

import Android.view.KeyEvent;
import Android.view.View.OnKeyListener;
import Android.widget.EditText;
import Android.widget.TextView;
4
LifeiSHot
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId != 0 || event.getAction() == KeyEvent.ACTION_DOWN) {
                // Action
                return true;
            } else {
                return false;
            }
        }
    });

Xml

<EditText
        Android:id="@+id/editText2"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:hint="@string/password"
        Android:imeOptions="actionGo|flagNoFullscreen"
        Android:inputType="textPassword"
        Android:maxLines="1" />
4
kreker

Cela devrait marcher

input.addTextChangedListener(new TextWatcher() {

           @Override
           public void afterTextChanged(Editable s) {}

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

           @Override    
           public void onTextChanged(CharSequence s, int start,
             int before, int count) {
               if( -1 != input.getText().toString().indexOf( "\n" ) ){
                   input.setText("Enter was pressed!");
                    }
           }
          });
4
ORY

Cela fonctionne correctement sur les téléphones LG Android. Cela empêche ENTER et d'autres caractères spéciaux d'être interprétés comme des caractères normaux. La touche Next ou Done apparaît automatiquement et la touche ENTER fonctionne comme prévu.

edit.setInputType(InputType.TYPE_CLASS_TEXT);
3
Milan Švec

Voici une fonction statique simple que vous pouvez insérer dans votre classe Utils ou Keyboards qui exécutera le code lorsque l'utilisateur appuiera sur la touche de retour sur un clavier matériel ou logiciel. C'est une version modifiée de l'excellente réponse de @ earlcasper

 /**
 * Return a TextView.OnEditorActionListener that will execute code when an enter is pressed on
 * the keyboard.<br>
 * <code>
 *     myTextView.setOnEditorActionListener(Keyboards.onEnterEditorActionListener(new Runnable()->{
 *         Toast.makeText(context,"Enter Pressed",Toast.LENGTH_SHORT).show();
 *     }));
 * </code>
 * @param doOnEnter A Runnable for what to do when the user hits enter
 * @return the TextView.OnEditorActionListener
 */
public static TextView.OnEditorActionListener onEnterEditorActionListener(final Runnable doOnEnter){
    return (__, actionId, event) -> {
        if (event==null) {
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                // Capture soft enters in a singleLine EditText that is the last EditText.
                doOnEnter.run();
                return true;
            } else if (actionId==EditorInfo.IME_ACTION_NEXT) {
                // Capture soft enters in other singleLine EditTexts
                doOnEnter.run();
                return true;
            } else {
                return false;  // Let system handle all other null KeyEvents
            }
        } else if (actionId==EditorInfo.IME_NULL) {
            // Capture most soft enters in multi-line EditTexts and all hard enters.
            // They supply a zero actionId and a valid KeyEvent rather than
            // a non-zero actionId and a null event like the previous cases.
            if (event.getAction()==KeyEvent.ACTION_DOWN) {
                // We capture the event when key is first pressed.
                return true;
            } else {
                doOnEnter.run();
                return true;   // We consume the event when the key is released.
            }
        } else {
            // We let the system handle it when the listener
            // is triggered by something that wasn't an enter.
            return false;
        }
    };
}
2
JohnnyLambada
   final EditText edittext = (EditText) findViewById(R.id.edittext);
    edittext.setOnKeyListener(new OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // If the event is a key-down event on the "enter" button
            if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
                    (keyCode == KeyEvent.KEYCODE_ENTER)) {
                // Perform action on key press
                Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
                return true;
            }
            return false;
        }
    });
2
Brinda Rathod

Tapez ce code dans votre éditeur pour qu'il puisse importer les modules nécessaires.

 query.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
            if(actionId == EditorInfo.IME_ACTION_DONE
                || actionId == EditorInfo.IME_ACTION_DONE
                    || keyEvent.getAction() == KeyEvent.ACTION_DOWN
                        || keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {

                // Put your function here ---!

                return true;

            }
            return false;
        }
    });
2
Sanjit Prasad

Le type d'entrée sur le champ de texte doit être text pour que ce que CommonsWare ait dit fonctionne. Juste essayé tout cela, sans inputType avant le procès et rien n’a fonctionné, Enter a continué à s’enregistrer en tant que soft. Après inputType = text, tout, y compris le setImeLabel, a fonctionné.

Exemple:Android:inputType="text"

2
Odaym

Un moyen fiable de répondre à une <entrée> dans un EditText consiste à utiliser TextWatcher , LocalBroadcastManager et BroadcastReceiver . Vous devez ajouter le bibliothèque de support v4 pour utiliser le LocalBroadcastManager. J'utilise le tutoriel à l'adresse vogella.com : 7.3 "Événements de diffusion locale avec LocalBroadcastManager" en raison de son code complet et concis, par exemple. Dans onTextChanged avant est l'index de la fin du changement avant le changement>; départ moins. Lorsque, dans TextWatcher, le thread d'interface utilisateur est occupé à mettre à jour les modifications de editText, nous envoyons donc une intention de réactiver BroadcastReceiver lorsque le thread d'interface utilisateur a terminé de mettre à jour editText.

import Android.content.Context;
import Android.content.Intent;
import Android.content.IntentFilter;
import Android.text.Editable;
//in onCreate:
editText.addTextChangedListener(new TextWatcher() {
  public void onTextChanged
  (CharSequence s, int start, int before, int count) {
    //check if exactly one char was added and it was an <enter>
    if (before==0 && count==1 && s.charAt(start)=='\n') {
    Intent intent=new Intent("enter")
    Integer startInteger=new Integer(start);
    intent.putExtra("Start", startInteger.toString()); // Add data
    mySendBroadcast(intent);
//in the BroadcastReceiver's onReceive:
int start=Integer.parseInt(intent.getStringExtra("Start"));
editText.getText().replace(start, start+1,""); //remove the <enter>
//respond to the <enter> here
1
earlcasper

Butterknife n'a pas encore répondu à cette question

LAYOUT XML

<Android.support.design.widget.TextInputLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:hint="@string/some_input_hint">

        <Android.support.design.widget.TextInputEditText
            Android:id="@+id/textinput"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:imeOptions="actionSend"
            Android:inputType="text|textCapSentences|textAutoComplete|textAutoCorrect"/>
    </Android.support.design.widget.TextInputLayout>

APP Java

@OnEditorAction(R.id.textinput)
boolean onEditorAction(int actionId, KeyEvent key){
    boolean handled = false;
    if (actionId == EditorInfo.IME_ACTION_SEND || (key.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
        //do whatever you want
        handled = true;
    }
    return handled;
}
0

Ajouter ces dépendants, et cela devrait fonctionner:

import Android.view.KeyEvent;
import Android.view.View;
import Android.widget.EditText;
0
Jacky Supit