Comment créer un texte EditText sur Android, de sorte que l'utilisateur ne puisse pas entrer un texte multiligne, mais que l'affichage soit toujours multiligne (c'est-à-dire que Word-wrap remplace le texte à droite)
C'est similaire à l'application SMS intégrée dans laquelle nous ne pouvons pas saisir de nouvelle ligne mais le texte est affiché sur plusieurs lignes.
Je sous-classerais le widget et remplacerais la gestion des événements de clé afin de bloquer la clé Enter
:
class MyTextView extends EditText
{
...
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode==KeyEvent.KEYCODE_ENTER)
{
// Just ignore the [Enter] key
return true;
}
// Handle all other keys in the default way
return super.onKeyDown(keyCode, event);
}
}
Il s'agit d'une méthode pour laquelle vous n'avez pas à remplacer la classe EditText. Vous attrapez et remplacez les nouvelles lignes par des chaînes vides.
myEditTextObject.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
for(int i = s.length(); i > 0; i--) {
if(s.subSequence(i-1, i).toString().equals("\n"))
s.replace(i-1, i, "");
}
String myTextString = s.toString();
}
});
Propriété en XML
Android:lines="5"
Android:inputType="textPersonName"
Celui-ci fonctionne pour moi:
<EditText
Android:inputType="textShortMessage|textMultiLine"
Android:minLines="3"
... />
Il affiche un smiley au lieu de la touche Entrée.
La réponse fournie par @Andreas Rudolph contient un bogue critique et ne doit pas être utilisée. Le code provoque une IndexOutOfBoundsException
lorsque vous passez du texte à l'intérieur de la EditText
qui contient plusieurs caractères de nouvelle ligne. Cela est dû au type de boucle utilisé. L'objet Editable
appelle la méthode afterTextChanged
dès que son contenu change (remplacer, supprimer, insérer).
Code correct:
edittext.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
/*
* The loop is in reverse for a purpose,
* each replace or delete call on the Editable will cause
* the afterTextChanged method to be called again.
* Hence the return statement after the first removal.
* http://developer.Android.com/reference/Android/text/TextWatcher.html#afterTextChanged(Android.text.Editable)
*/
for(int i = s.length()-1; i >= 0; i--){
if(s.charAt(i) == '\n'){
s.delete(i, i + 1);
return;
}
}
}
});
Essaye ça:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER)
{
//Nothing
return true;
}
return super.onKeyDown(keyCode, event);
}
Je teste cela et cela semble fonctionner:
EditText editText = new EditText(context);
editText.setSingleLine(false);
editText.setInputType(Android.text.InputType.TYPE_CLASS_TEXT | Android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT);
Vous pouvez le définir à partir du XML comme ceci:
Android:imeOptions="actionDone"
Android:inputType="text"
Android:maxLines="10"
n'oubliez pas Android:inputType="text"
, si vous ne le définissez pas, cela ne fonctionne pas. Je ne sais pas pourquoi… .. De plus, n'oubliez pas de changer maxLines
en votre valeur préférée.
Ajoutez simplement
Android:singleLine="true"
à votre EditText
Voici une réponse plus correcte qui n'affiche pas la touche Entrée du clavier IME:
// IMPORTANT, do this before any of the code following it
myEditText.setSingleLine(true);
// IMPORTANT, to allow wrapping
myEditText.setHorizontallyScrolling(false);
// IMPORTANT, or else your edit text would wrap but not expand to multiple lines
myEditText.setMaxLines(6);
En outre, vous pouvez remplacer setSingleLine(true)
par l'un des Android:inputType
explicites du fichier de mise en forme XML ou setInputType(InputType.*)
du code - dans lequel, le type d'entrée utilisé est tout ce que vous savez limiter l'entrée à une seule ligne seulement (c.-à-d. tout ce qui appelle setSingleLine(true)
déjà implicitement).
Explication:
Ce que fait setSingleLine(true)
appelle les fonctions setHorizontallyScrolling(true)
et setLines(1)
implicitement, parallèlement à la modification de certains paramètres du clavier de l'IME pour désactiver la touche Entrée.
À son tour, l'appel à setLines(1)
équivaut à appeler setMinLines(1)
et setMaxLines(1)
en un seul appel.
Certains types d’entrée (c’est-à-dire les constantes de InputType.TYPE_*
) appellent setSingleLine(true)
implicitement ou du moins ont le même effet.
Conclusion:
Donc, pour obtenir ce que le PO veut, nous luttons simplement contre ces paramètres implicites en inversant ces appels implicites.
La réponse acceptée a tellement bien fonctionné que j'ai copié du texte avec des sauts de ligne dans le texte d'édition. J'ai donc ajouté onTextContextMenuItem pour surveiller l'action de collage.
@Override
public boolean onTextContextMenuItem(int id) {
boolean ret = super.onTextContextMenuItem(id);
switch (id) {
case Android.R.id.paste:
onTextPaste();
break;
}
return ret;
}
public void onTextPaste() {
if (getText() == null)
return;
String text = getText().toString();
text = text.replaceAll(System.getProperty("line.separator"), " ");
text = text.replaceAll("\\s+", " ");
setText(text);
}
Pour un URI vous pouvez utiliser:
Android:inputType="textUri"
Android:lines="1"
Android:maxLength="128"
Autrement, Android:inputType="textPersonName"
, comme mentionné ci-dessus, fonctionne pour d'autres noms de texte tels que EditText, etc.
Voici la solution ....
<EditText
Android:id="@+id/editText"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:maxLength="150"
Android:textSize="15dp"
Android:imeOptions="actionDone"
Android:inputType="text|textMultiLine"/>
Utilisation en classe Java
editText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (keyCode==KeyEvent.KEYCODE_ENTER)
{
// Just ignore the [Enter] key
return true;
}
// Handle all other keys in the default way
return (keyCode == KeyEvent.KEYCODE_ENTER);
}
});
EditText textView = new EditText(activity);
...
textView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if(KeyEvent.KEYCODE_ENTER == keyEvent.getKeyCode()) {
return false;
}
.......
}
});
Vous pouvez changer le bouton d'action du code
editText.imeOptions = EditorInfo.IME_ACTION_DONE
editText.setRawInputType(InputType.TYPE_CLASS_TEXT)
Xml
Android:inputType="textMultiLine"
<EditText
Android:id="@+id/Msg"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_marginTop="5dip"
Android:lines="5"
Android:selectAllOnFocus="true"
Android:hint="Skriv meddelande...\n(max 100tkn)"/>
EditText et = (EditText)findViewById(R.id.Msg);
String strTmp = et.getText().toString();
strTmp = strTmp.replaceAll("\\n"," ");
Je vais donner une autre option afin que vous n'ayez pas à sous-classe EditText. Créez une InputFilter
qui filtre les sauts de ligne. Ensuite, utilisez EditText.addInputFilter
.
Le code source pour un tel filtre d’entrée est ici: https://Gist.github.com/CapnSpellcheck/7c72830e43927380daf5205100c93977
Vous pouvez passer 0 dans le constructeur et il n'autorisera aucune nouvelle ligne. En outre, vous pouvez combiner cela avec l'un des autres réglages tels que Android:imeOptions="actionDone"
, car cela aidera à améliorer l'expérience sur certains appareils.
Ajouter cette propriété à la variable EditText
XML fonctionne pour moi:
Android:lines="1"
Il permet aux utilisateurs de saisir des caractères de nouvelle ligne, mais la hauteur de EditText
n’augmente pas.