Placer le curseur à la fin du texte dans EditText


884

Je modifie la valeur d'un EditTexton keyListener.

Mais quand je change le texte, le curseur se déplace vers le début du EditText. J'ai besoin que le curseur soit à la fin du texte.

Comment déplacer le curseur à la fin du texte dans a EditText.


3
Je suis tombé sur le même problème. Mais ce que je me suis demandé, c'est pourquoi cela se produit, afin que je puisse résoudre le problème avant au lieu d'avoir à déplacer le curseur moi-même.
kaneda

3
@kaneda Je suis totalement d'accord, mais cela aurait été utile si vous aviez ajouté la solution réelle.
AgentKnopf

1
@Zainodis C'était juste une pensée. Comme je l'ai dit, je suis tombé sur le même problème, ce qui ne signifie pas nécessairement que j'ai trouvé la solution. Dans mon cas, j'ai eu le problème avec les EditTexts comme éléments d'un ListView. Quant à l'expérimentation, j'ai fait quelques changements sur le ListViewcode source lui-même, qui est une bête assez complexe, et testé sur l'émulateur. Elle était liée à la gestion du contrôle de la concentration effectuée par le composant. Alors bien sûr, ce n'est pas une solution que je pourrais donner pour aider notre ami. :)
kaneda


Cela ne fonctionne pas dans le OnFocusChangedrappel. La solution consiste à placer setSelection dans un exécutable et à l'exécuter sur le thread principal. Vérifiez ici stackoverflow.com/a/32156989/4514796
Ali Nem

Réponses:


1320

Essaye ça:

EditText et = (EditText)findViewById(R.id.inbox);
et.setSelection(et.getText().length());

15
Cela ne fonctionne pas dans mon cas. La méthode setSelection () semble n'avoir aucun effet. Ma vue EditText contient des ImagesSpans. Existe-t-il un autre type de solution?
toobsco42

@marqss, j'ai eu le même problème et a parfaitement fonctionné pour moi. J'utilisais EditText sur une boîte de dialogue et préremplissais du texte à partir de l'écran principal. Lorsque cela se produit, le curseur restait au début et non à la fin, mais après avoir essayé votre suggestion, tout va bien, comme je le voulais. Merci d'avoir posté ceci.
Vincy

4
Hé @ Mullay, je le gère maintenant en remplaçant la onSelectionChanged()méthode d'une EditTextclasse: public void onSelectionChanged(int start, int end) { CharSequence text = getText(); if (text != null) { if (start != text.length() || end != text.length()) { setSelection(text.length(), text.length()); return; } } super.onSelectionChanged(start, end); }
toobsco42

19
Vous devrez peut-être utiliser et.post (new Runnable ({... et.setSel ... pour entrer dans la file d'attente. C'est parce qu'Android attend de faire des trucs de mise en page jusqu'à un meilleur moment en publiant donc si vous essayez de définirSelection avant que le système ne soit terminé, il
annulera

1
Cela fonctionne ici, merci pour votre réponse.Mais vous devriez faire comme ceci: editText.setText (s); editText.setSelection (editText.getText (). length ()); // après setText
smileVann

224

Il existe une fonction appelée append pour ediitext qui ajoute la valeur de chaîne à la valeur edittext actuelle et place le curseur à la fin de la valeur. Vous pouvez avoir la valeur de chaîne comme valeur ediitext actuelle elle-même et appeler append ();

myedittext.append("current_this_edittext_string"); 

1
Si vous avez déjà du texte dans votre EditText, écrivez simplementmyedittext.append("");
ymerdrengene

4
@ymerdrengene simplement postuler myedittext.append("");n'a pas fonctionné pour moi!
Chintan Shah

4
C'est parfait car il remplace simplement la ligne de code que j'avais. J'utilisais edittextfield.setText et je l'ai juste échangé pour l'ajout. Très simple.
theblitz

Dépend de l'utilisation si cela fonctionne ou non. Pour moi, ce n'était pas le cas. L'utilisation Selectionest la bonne façon de réaliser cette OMI.
sud007

140

Kotlin :

placez le curseur sur la position de départ :

val editText = findViewById(R.id.edittext_id) as EditText
editText.setSelection(0)

placez le curseur à la fin du EditText :

val editText = findViewById(R.id.edittext_id) as EditText
editText.setSelection(editText.text.length)

Sous Code, vous placez le curseur après le deuxième caractère:

val editText = findViewById(R.id.edittext_id) as EditText
editText.setSelection(2)

JAVA :

placez le curseur sur la position de départ :

 EditText editText = (EditText)findViewById(R.id.edittext_id);
 editText.setSelection(0);

placez le curseur à la fin du EditText :

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(editText.getText().length());

Sous Code, vous placez le curseur après le deuxième caractère:

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(2);

1
Pourrait remplacer findViewById(R.id.edittext_id) as EditTextavec findViewById<EditText>(R.id.edittext_id)ou tout simplement éviter la coulée si vous utilisezAPI 26+
Evin1_

97

Si vous avez appelé setTextauparavant et que le nouveau texte n'a pas reçu d'appel de phase de mise en page setSelectiondans un exécutable distinct déclenché par View.post(Runnable)(republier à partir de cette rubrique).

Donc, pour moi, ce code fonctionne:

editText.setText("text");
editText.post(new Runnable() {
         @Override
         public void run() {
             editText.setSelection(editText.getText().length());
         }
});

Edit 16/05/2019: En ce moment j'utilise l'extension Kotlin pour ça:

fun EditText.placeCursorToEnd() {
    this.setSelection(this.text.length)
}

puis - editText.placeCursorToEnd ().


Merci, cela a vraiment fonctionné pour moi. J'essayais d'appeler setSelection mais cela ne fonctionnera pas. Dans mon cas, j'essayais de définir un préfixe fixe pour modifier le texte, et donc après avoir défini le préfixe, je devais placer le curseur sur la fin du préfixe pour que l'utilisateur puisse entrer des données après le préfixe. Puisque je faisais setSelection dans le constructeur d'un TextWatcher, c'est peut-être pourquoi cela n'a pas fonctionné. Mais votre solution a très bien fonctionné!
Wand Maker

J'utilise cette méthode de publication dans la méthode Clickablespan de mon MultiAutoCompleteTextView et cela fonctionne ..... Je veux que le curseur se déplace à la fin une fois que l'icône de suppression dans la plage de texte est cliquée ... Cela fonctionne dans tous les derniers mobiles Android. ..mais dans les anciennes versions cela prend un certain temps après le premier clic ... tous mes autres articles ne deviennent pas cliquables ... aucun indice ??
VijayRaj

1
Je ne sais pas pourquoi, mais c'est le seul qui fonctionne pour moi! Mon texte d'édition a un écouteur focus / texte modifié et est enveloppé dans un TextInputLayout. Une de ces choses est de tout gâcher.
Daniel Wilson

42

Vous pouvez également placer le curseur à la fin du texte dans la EditTextvue comme ceci:

EditText et = (EditText)findViewById(R.id.textview);
int textLength = et.getText().length();
et.setSelection(textLength, textLength);

27
editText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        editText.setSelection(editText.getText().length());
        return false;
    }
});

21

Ceci est une autre solution possible:

et.append("");

Essayez cette solution si elle ne fonctionne pas pour une raison quelconque:

et.setSelection(et.getText().length());

12
/**
 * Set cursor to end of text in edittext when user clicks Next on Keyboard.
 */
View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean b) {
        if (b) {
            ((EditText) view).setSelection(((EditText) view).getText().length());
        }
    }
};

mEditFirstName.setOnFocusChangeListener(onFocusChangeListener); 
mEditLastName.setOnFocusChangeListener(onFocusChangeListener);

Ça marche bien pour moi!


12

Dans mon cas, j'ai créé le kotlin ext suivant. fonction, peut être utile à quelqu'un

 private fun EditText.focus(){
        requestFocus()
        setSelection(length())
    }

Ensuite, utilisez comme suit

mEditText.focus()

12

Si votre EditText n'est pas clair:

editText.setText("");
editText.append("New text");

ou

editText.setText(null);
editText.append("New text");

12

Vous devriez pouvoir y parvenir à l'aide de la EditText'sméthode setSelection(), voir ici


10

je pense que cela peut réaliser ce que vous voulez.

 Editable etext = mSubjectTextEditor.getText();
 Selection.setSelection(etext, etext.length());

Si mes observations sont correctes, cela génère une instance de android.widget.TextView $ IClipboardDataPasteEventImpl pour chaque widget. Je me suis retrouvé avec des tonnes d'entre eux. Apparemment, ils finissent par être nettoyés, mais semblent augmenter la consommation de mémoire. J'ai eu 12 instances d'un dialogue, c'est seulement le dominateur (ce qui le maintient en vie) qui est l'instance mentionnée ci-dessus.
AgentKnopf

Placer ce morceau de code à la position appropriée dans le code (où vous ajoutez du texte directement à EText). Merci!
sud007

9

La question est ancienne et répondue, mais je pense qu'il peut être utile d'avoir cette réponse si vous souhaitez utiliser les nouveaux outils DataBinding pour Android, il suffit de définir cela dans votre XML:

<data>
    <variable name="stringValue" type="String"/>
</data>
...
<EditText
        ...
        android:text="@={stringValue}"
        android:selection="@{stringValue.length()}"
        ...
/>

6

entrez la description de l'image ici

Bonjour Essayez ceci

 <EditText
       android:id="@+id/edt_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="Hello World!"
       android:cursorVisible="true"/>

EditText editText = findViewById(R.id.editText); editText.setSelection(editText.getText().length()); // End pointLe curseur


5

Si vous souhaitez sélectionner tout le texte et entrer simplement un nouveau texte au lieu de l'ancien, vous pouvez utiliser

    android:selectAllOnFocus="true"

5

Cela marche

Editable etext = edittext.getText();
Selection.setSelection(etext,edittext.getText().toString().length());

5

editText.setSelectionest la magie ici. Fondamentalement, la sélection vous permet de placer le curseur à la position souhaitée.

EditText editText = findViewById(R.id.editText);
editText.setSelection(editText.getText().length());

Cela place le curseur à la fin de EditText. editText.getText().length()Vous donne essentiellement la longueur du texte. Ensuite, vous utilisez setSelectionavec longueur.

editText.setSelection(0);

C'est pour placer le curseur à la position de départ (0).


4

Tous les autres codes que j'ai testés ne fonctionnaient pas bien car l'utilisateur pouvait toujours placer le curseur / curseur n'importe où au milieu de la chaîne (ex.: 12 | 3.00 - où | est le curseur). Ma solution place toujours le curseur à la fin de la chaîne chaque fois que le toucher se produit sur le EditText.

La solution ultime est:

// For a EditText like:
<EditText
                android:id="@+id/EditTextAmount"
                android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:hint="@string/amount"
                android:layout_weight="1"
                android:text="@string/zero_value"
                android:inputType="text|numberDecimal"
                android:maxLength="13"/>

@ string / amount = "0.00" @ string / zero_value = "0.00"

// Create a Static boolean flag
private static boolean returnNext; 


// Set caret/cursor to the end on focus change
EditTextAmount.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View editText, boolean hasFocus) {
                if(hasFocus){
                    ((EditText) editText).setSelection(((EditText) editText).getText().length());
                }
            }
        });

// Create a touch listener and put caret to the end (no matter where the user touched in the middle of the string)
EditTextAmount.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View editText, MotionEvent event) {
                ((EditText) editText).onTouchEvent(event);
                ((EditText) editText).setSelection(((EditText) editText).getText().length());
                return true;
            }
        });


// Implement a Currency Mask with addTextChangedListener
EditTextAmount.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String input = s.toString();
                String output = new String();
                String buffer = new String();
                String decimals = new String();
                String numbers = Integer.toString(Integer.parseInt(input.replaceAll("[^0-9]", "")));

                if(returnNext){
                    returnNext = false;
                    return;
                }

                returnNext = true;

                if (numbers.equals("0")){
                    output += "0.00";
                }
                else if (numbers.length() <= 2){
                    output += "0." + String.format("%02d", Integer.parseInt(numbers));
                }
                else if(numbers.length() >= 3){
                    decimals = numbers.substring(numbers.length() - 2);
                    int commaCounter = 0;
                    for(int i=numbers.length()-3; i>=0; i--){
                        if(commaCounter == 3){
                            buffer += ",";
                            commaCounter = 0;
                        }
                        buffer += numbers.charAt(i);
                        commaCounter++;
                    }
                    output = new StringBuilder(buffer).reverse().toString() + "." + decimals;
                }
                EditTextAmount.setText(output);
                EditTextAmount.setSelection(EditTextAmount.getText().length());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                /*String input = s.toString();
                if(input.equals("0.0")){
                    EditTextAmount.setText("0.00");
                    EditTextAmount.setSelection(EditTextAmount.getText().length());
                    return;
                }*/
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

J'espère que cela aide!


3

Pour ViewModel, LiveData et liaison de données

J'avais besoin de cette fonctionnalité pour EditText avec le support multiligne dans mon application notes. Je voulais que le curseur se trouve à la fin du texte lorsque l'utilisateur accède au fragment contenant du texte de note.

La solution proposée par le djleop se rapproche. Mais le problème avec cela est que, si l'utilisateur place le curseur quelque part au milieu du texte à modifier et commence à taper, le curseur sautera à la fin du texte à nouveau. Cela est arrivé parce que leLiveData émettrait la nouvelle valeur et le curseur sauterait à la fin du texte à nouveau, ce qui empêcherait l'utilisateur de modifier le texte quelque part au milieu.

Pour résoudre ce problème, je l'utilise MediatorLiveDataet lui attribue la longueur d' Stringune seule fois à l'aide d'un indicateur. Cela provoquera la lecture de la valeur par LiveData une seule fois, c'est-à-dire lorsque l'utilisateur accède au fragment. Après cela, l'utilisateur peut placer le curseur là où il veut éditer le texte.

ViewModel

private var accessedPosition: Boolean = false

val cursorPosition = MediatorLiveData<Event<Int>>().apply {
    addSource(yourObject) { value ->
        if(!accessedPosition) {
            setValue(Event(yourObject.note.length))
            accessedPosition = true
        }
    }
}

Voici yourObjectune autre LiveData extraite de la base de données qui contient le texte de chaîne que vous affichez dans leEditText .

MediatorLiveDataLiez ensuite cela à votre EditText à l'aide de l'adaptateur de liaison.

XML

Utilise la liaison de données bidirectionnelle pour afficher le texte ainsi que pour accepter la saisie de texte.

<!-- android:text must be placed before cursorPosition otherwise we'll get IndexOutOfBounds exception-->
<EditText
    android:text="@={viewModel.noteText}"
    cursorPosition="@{viewModel.cursorPosition}" />

Adaptateur de reliure

@BindingAdapter("cursorPosition")
fun bindCursorPosition(editText: EditText, event: Event<Int>?) {
    event?.getContentIfNotHandled()?.let { editText.setSelection(it) }
}

Event classe

La Eventclasse ici est comme un SingleLiveEvent écrit par Jose Alcérreca de Google. Je l'utilise ici pour prendre en charge la rotation de l'écran. L'utilisation du single Eventgarantit que le curseur ne sautera pas à la fin du texte lorsque l'utilisateur modifie le texte quelque part au milieu et que l'écran pivote. Il conservera la même position lorsque l'écran pivotera.

Voici la Eventclasse:

open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}

C'est la solution qui fonctionne pour moi et offre une bonne expérience utilisateur. J'espère que cela vous aidera aussi dans vos projets.


Cette réponse doit être très avancée. Merci beaucoup
Abdul Rahman Shamair

2

similaire à la réponse de @Anh Duy, mais cela n'a pas fonctionné pour moi. J'ai également eu besoin que le curseur se déplace jusqu'à la fin uniquement lorsque l'utilisateur appuie sur le texte d'édition et qu'il est toujours possible de sélectionner la position du curseur par la suite, c'est le seul code qui a fonctionné pour moi

boolean textFocus = false; //define somewhere globally in the class

//in onFinishInflate() or somewhere
editText.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {

        editText.onTouchEvent(event);

        if(!textFocus) {
            editText.setSelection(editText.getText().length());
            textFocus = true;
        }

        return true;
    }
});

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        textFocus = false;
    }
});

2

Cela fait l'affaire en toute sécurité :

    editText.setText("");
    if (!TextUtils.isEmpty(text)) {
        editText.append(text);
    }


2

Les réponses ci-dessus n'ont pas fonctionné pour moi. J'ai donc découvert une nouvelle solution. Cela peut être utile à quelqu'un. J'utilise la dernière version d'Android Studio, c'est-à-dire 3.5 à la date actuelle. C'est peut-être la raison pour laquelle les réponses ci-dessus n'ont montré aucun effet.

CODE:

EditText available_seats = findViewById(R.id.available_seats);
Selection.setSelection(available_seats.getText(),available_seats.getText().length());

Ici, le 1er argument est la valeur de texte pouvant être étendue avec laquelle vous voulez jouer, tandis que le 2e argument est la valeur d'index. Depuis, nous voulons que le curseur soit à la fin du texte, nous avons pris getText (). Length () qui retourne la longueur du texte


1
Mon plaisir! Codage heureux!
Prajwal W

1
public class CustomEditText extends EditText {
    public CustomEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomEditText(Context context) {
        super(context);
    }

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


    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        this.setSelection(this.getText().length());
    }

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

    }
}

Utilisez ce CustomEditText dans votre fichier XML, cela fonctionnera. J'ai testé cela et cela fonctionne pour moi.


1

Si vous souhaitez placer le curseur à la fin du texte dans la vue EditText

 EditText rename;
 String title = "title_goes_here";
 int counts = (int) title.length();
 rename.setSelection(counts);
 rename.setText(title);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.