Coloque el cursor al final del texto en EditText

884

Estoy cambiando el valor de un EditTextenkeyListener .

Pero cuando cambio el texto, el cursor se mueve al comienzo de EditText. Necesito que el cursor esté al final del texto.

Cómo mover el cursor al final del texto en a EditText.

Manu
fuente
3
Me encontré con el mismo problema. Pero lo que me pregunté mejor es por qué está sucediendo esto, para poder resolver el problema antes en lugar de tener que trasladarlo yo mismo.
kaneda
3
@kaneda Estoy totalmente de acuerdo, sin embargo, habría sido útil si hubiera agregado la solución real.
AgentKnopf
1
@Zainodis Fue solo un pensamiento. Como dije, me encontré con el mismo problema, lo que no necesariamente significa que he encontrado la solución. En mi caso tuve el problema con la EditTexts como elementos de a ListView. En cuanto a la experimentación, hice algunos cambios en el ListViewcódigo fuente en sí, que es una bestia bastante compleja, y probé en el emulador. Estaba relacionado con la gestión de control de foco realizada por el componente. Por supuesto, no es una solución que pueda dar para ayudar a nuestro amigo. :)
kaneda
2
posible duplicado de Android edittext - problema del cursor
settextmethod
Esto no funciona dentro de la OnFocusChangeddevolución de llamada. La solución es poner setSelection dentro de un ejecutable y ejecutarlo en el hilo principal. Consulte aquí stackoverflow.com/a/32156989/4514796
Ali Nem

Respuestas:

1320

Prueba esto:

EditText et = (EditText)findViewById(R.id.inbox);
et.setSelection(et.getText().length());
Marqs
fuente
15
Esto no funciona en mi caso. El método setSelection () parece no tener efecto. Mi vista EditText contiene ImageSpans. ¿Hay algún otro tipo de solución?
toobsco42
@marqss, tuve el mismo problema y funcionó perfectamente para mí. Estaba usando EditText en un diálogo y rellenando previamente el texto desde la pantalla principal. Cuando eso sucede, el cursor se quedaba al principio y no al final, pero después de probar su sugerencia, todo está bien, como quería. Gracias por publicar esto.
Vincy
44
Hola @Mullay, ahora lo estoy manejando al anular el onSelectionChanged()método de una EditTextclase: 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
Es posible que tenga que usar et.post (nuevo Runnable ({... et.setSel ... para entrar en la cola. Esto se debe a que Android espera hacer algunas cosas de diseño hasta un mejor momento publicando) si intenta establecer SetSelection antes de que el sistema esté terminado, deshacerá tu trabajo.
MinceMan
1
Funciona aquí, gracias por su respuesta. Pero debe hacer esto: editText.setText (s); editText.setSelection (editText.getText (). length ()); // después de setText
smileVann
224

Hay una función llamada append para ediitext que agrega el valor de la cadena al valor actual de edittext y coloca el cursor al final del valor. Puede tener el valor de cadena como el valor actual de ediitext y llamar a append ();

myedittext.append("current_this_edittext_string"); 
James
fuente
1
Si ya tiene texto en su EditText, simplemente escribamyedittext.append("");
ymerdrengene
44
¡@ymerdrengene solo postular myedittext.append("");no funcionó para mí!
Chintan Shah
44
Esto es perfecto porque simplemente reemplaza la línea de código que tenía. Estaba usando edittextfield.setText y simplemente lo cambié por agregar. Muy simple.
theblitz
Depende del uso si eso funciona o no. Para mí no fue así. Usar Selectiones la forma correcta de lograr esa OMI.
sud007
140

Kotlin :

coloque el cursor en la posición inicial :

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

coloque el cursor al final del EditText :

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

El siguiente código es colocar el cursor después del segundo carácter:

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

JAVA :

coloque el cursor en la posición inicial :

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

coloque el cursor al final del EditText :

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

El siguiente código es colocar el cursor después del segundo carácter:

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(2);
Mr.vicky patel
fuente
1
Podría reemplazar findViewById(R.id.edittext_id) as EditTextcon findViewById<EditText>(R.id.edittext_id)o simplemente evitar el vaciado si se utilizaAPI 26+
Evin1_
97

Si llamó setTextantes y el nuevo texto no obtuvo la fase de diseño, llame setSelectiona un ejecutable separado disparado por View.post(Runnable)(reenvío de este tema).

Entonces, para mí, este código funciona:

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

Editar 16/05/2019: En este momento estoy usando la extensión de Kotlin para eso:

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

y luego - editText.placeCursorToEnd ().

Anton Derevyanko
fuente
Gracias, esto realmente funcionó para mí. Intenté llamar a setSelection pero no funcionará. En mi caso, estaba tratando de establecer un prefijo fijo para editar texto, por lo que después de establecer el prefijo, necesitaba establecer el cursor al final del prefijo para que el usuario pueda ingresar datos después del prefijo. Como estaba haciendo setSelection en el constructor de un TextWatcher, puede ser por eso que no funcionó. ¡Pero su solución funcionó muy bien!
Wand Maker
Estoy usando este método de publicación en mi método Clickablespan de MultiAutoCompleteTextView y funciona ... Quiero que el cursor se mueva al final una vez que se hace clic en el icono de borrar en el lapso de texto ... Funciona en todos los últimos móviles Android. ... pero en las versiones anteriores lleva algún tiempo después del primer clic ... todos mis otros elementos no se pueden hacer clic ... ¿alguna pista?
VijayRaj
1
¡No sé por qué, pero este es el único que funciona para mí! Mi texto de edición tiene un escucha de foco / texto cambiado y está envuelto en un TextInputLayout. Una de esas cosas es estropearlo.
Daniel Wilson
42

También puede colocar el cursor al final del texto en la EditTextvista de esta manera:

EditText et = (EditText)findViewById(R.id.textview);
int textLength = et.getText().length();
et.setSelection(textLength, textLength);
toobsco42
fuente
27
editText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        editText.setSelection(editText.getText().length());
        return false;
    }
});
Mario
fuente
21

Esta es otra posible solución:

et.append("");

Simplemente pruebe esta solución si no funciona por alguna razón:

et.setSelection(et.getText().length());
Kreshnik
fuente
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);

¡Funciona bien para mí!

Anh Duy
fuente
12

En mi caso, creé el siguiente kotlin ext. función, puede ser útil para alguien

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

Luego use de la siguiente manera

mEditText.focus()
Igor Siqueira
fuente
12

Si su EditText no está claro:

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

o

editText.setText(null);
editText.append("New text");
Leo Droidcoder
fuente
12

Deberías poder lograrlo con la ayuda del EditText'smétodo setSelection(), mira aquí

Maximus
fuente
10

Creo que esto puede lograr lo que quieres.

 Editable etext = mSubjectTextEditor.getText();
 Selection.setSelection(etext, etext.length());
Li Che
fuente
Si mis observaciones son correctas, esto genera una instancia de android.widget.TextView $ IClipboardDataPasteEventImpl para cada widget. Terminé con toneladas de ellos. Aparentemente, finalmente se limpian, pero parecen aumentar el consumo de memoria. Tuve 12 instancias de un diálogo, es solo el dominador (lo que lo mantiene vivo) es la instancia mencionada anteriormente.
AgentKnopf
Colocando ese fragmento de código en la posición apropiada en el código (donde está agregando texto directamente a EText). ¡Gracias!
sud007
9

La pregunta es antigua y está respondida, pero creo que puede ser útil tener esta respuesta si desea utilizar las nuevas herramientas DataBinding para Android, solo configúrelo en su XML:

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

ingrese la descripción de la imagen aquí

Hola Intenta esto

 <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 pointCursor

Rahul Patil
fuente
5

Si desea seleccionar todo el texto e ingresar texto nuevo en lugar del anterior, puede usar

    android:selectAllOnFocus="true"
ar-g
fuente
5

Esto funciona

Editable etext = edittext.getText();
Selection.setSelection(etext,edittext.getText().toString().length());
Hardik Vasani
fuente
5

editText.setSelectionEs la magia aquí. Básicamente, la selección le permite colocar el cursor en cualquier posición que desee.

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

Esto coloca el cursor al final de EditText. Básicamente editText.getText().length()te da la longitud del texto. Luego lo usas setSelectioncon longitud.

editText.setSelection(0);

Es para colocar el cursor en la posición inicial (0).

Khemraj
fuente
4

Todos los demás códigos que probé no funcionaron bien debido al hecho de que el usuario aún podía colocar el cursor / cursor en cualquier lugar en el medio de la cadena (ej .: 12 | 3.00 - donde | está el cursor). Mi solución siempre coloca el cursor al final de la cadena cada vez que se toca en EditText.

La solución definitiva es:

// 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) {

            }
        });

¡Espero eso ayude!

Daniel Almeida
fuente
3

Para ViewModel, LiveData y Enlace de datos

Necesitaba esta funcionalidad EditTextcon soporte multilínea en mi aplicación de notas. Quería el cursor al final del texto cuando el usuario navega hacia el fragmento que tiene texto de nota.

La solución sugerida por el djleop se acerca. Pero el problema con esto es que, si el usuario coloca el cursor en algún lugar en el medio del texto para editarlo y comienza a escribir, el cursor volvería al final del texto. Esto sucedió porque elLiveData emitiría el nuevo valor y el cursor saltaría al final del texto nuevamente, lo que provocaría que el usuario no pudiera editar el texto en algún lugar en el medio.

Para resolver esto, lo uso MediatorLiveDatay le asigno la longitud de Stringsolo una vez usando una bandera. Esto hará que LiveData lea el valor solo una vez, es decir, cuando el usuario navegue hasta el fragmento. Después de eso, el usuario puede colocar el cursor en cualquier lugar donde desee editar el texto allí.

ViewModel

private var accessedPosition: Boolean = false

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

Aquí, yourObjecthay otro LiveData recuperado de la base de datos que contiene el texto de cadena que está mostrando en elEditText .

Luego vincule esto MediatorLiveDataa su EditText usando un adaptador de encuadernación.

XML

Utiliza el enlace de datos bidireccional para mostrar texto y aceptar la entrada de texto.

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

Adaptador de enlace

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

Event clase

La Eventclase aquí es como un evento SingleLiveEvent escrito por José Alcérreca de Google. Lo uso aquí para encargarme de la rotación de la pantalla. El uso del sencillo Eventasegurará que el cursor no salte al final del texto cuando el usuario esté editando el texto en algún lugar en el medio y la pantalla gire. Mantendrá la misma posición cuando la pantalla gire.

Aquí está la Eventclase:

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
}

Esta es la solución que funciona para mí y proporciona una buena experiencia de usuario. Espero que ayude en sus proyectos también.

Yogesh Umesh Vaity
fuente
Esta respuesta debe estar muy arriba. Muchas gracias
Abdul Rahman Shamair
2

similar a la respuesta de @Anh Duy, pero no funcionó para mí. También necesitaba que el cursor se moviera al final solo cuando el usuario toca el texto de edición y aún así puede seleccionar la posición del cursor después, este es el único código que me ha funcionado

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;
    }
});
Fonix
fuente
2

Esto hace el truco de manera segura :

    editText.setText("");
    if (!TextUtils.isEmpty(text)) {
        editText.append(text);
    }
Alécio Carvalho
fuente
2
etSSID.setSelection(etSSID.getText().length());
siby varghese
fuente
2

Las respuestas anteriores no funcionaron para mí. Entonces descubrí una nueva solución. Esto puede ser útil para alguien. He estado usando la última versión de Android Studio, es decir, 3.5 según la fecha actual. Tal vez esa podría ser la razón por la cual las respuestas anteriores no mostraron ningún efecto.

CÓDIGO:

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

Aquí, el primer argumento es el valor de texto Spannable con el que desea jugar, mientras que el segundo argumento es el valor del índice. Como queremos el cursor al final del texto, tomamos getText (). Length () que devuelve la longitud del texto

Prajwal W
fuente
1
¡El gusto es mio! ¡Feliz codificación!
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) {

    }
}

Utilice este CustomEditText en su archivo XML, esto funcionará. He probado esto y está funcionando para mí.

kishna.147
fuente
1

Si desea colocar el cursor al final del texto en la vista Editar texto

 EditText rename;
 String title = "title_goes_here";
 int counts = (int) title.length();
 rename.setSelection(counts);
 rename.setText(title);
Mujahid Khan
fuente