945

I am changing the value of an EditText on keyListener.

But when I change the text the cursor is moving to the beginning of the EditText. I need the cursor to be at the end of the text.

How to move the cursor to the end of the text in a EditText.

Yogesh Umesh Vaity
  • 16,749
  • 10
  • 82
  • 69
Manu
  • 9,459
  • 3
  • 12
  • 3
  • 3
    I came across the same issue. But what I asked myself better is why this is happening, so that I could resolve the issue before instead of having to move the caret myself. – kaneda Dec 11 '12 at 18:55
  • 4
    @kaneda I totally agree, however it would have been helpful if you had added the actual solution. – AgentKnopf Jan 03 '13 at 07:47
  • 1
    @Zainodis It was just a thought. Like I said I came across the same issue, which does not necessarily means that I've found the solution. In my case I had the issue with the `EditText`s as items of a `ListView`. As for experimentation, I made some changes on the `ListView` source code itself, which is a rather complex beast, and tested on the emulator. It was related to focus control management made by the component. So of course it's not a solution I could give to help our friend. :) – kaneda Jan 03 '13 at 11:55
  • 2
    possible duplicate of [Android edittext - settextmethod cursor issue](http://stackoverflow.com/questions/5141776/android-edittext-settextmethod-cursor-issue) – AZ_ Apr 23 '15 at 08:08
  • This does not work inside `OnFocusChanged` callback. The solution there is to put setSelection inside a runnable and run it on main thread. Check here https://stackoverflow.com/a/32156989/4514796 – Ali Nem May 06 '20 at 10:34

25 Answers25

1381

Try this:

UPDATE:

Kotlin:

editText.setSelection(editText.text.toString().length)//placing cursor at the end of the text

Java:

editText.setSelection(editText.getText().length());
Kishan Solanki
  • 8,893
  • 2
  • 51
  • 54
Marqs
  • 16,260
  • 4
  • 26
  • 40
  • 16
    This doesnt work in my case. The setSelection() method seems to have no effect. My EditText view contains ImageSpans. Is there some other kind of workaround? – toobsco42 Jan 03 '13 at 07:57
  • @marqss, I had the same issue and worked perfectly for me. I was using EditText on a Dialog and pre-populating text from the main screen. When that happens the cursor was staying at the beginning and not at the end but after I tried your suggestion everything is just fine, the way I wanted. Thank you for posting this. – Vincy Jan 25 '13 at 16:19
  • @toobsco42, try adding the line et.setSelection(et.getText().length());, whenever you change the text, like you may change the text on clicking a button. That's because the length of the EditText gets changed. – Mullaly Feb 28 '13 at 12:48
  • 4
    Hey @Mullay, I am now handling it by overriding the `onSelectionChanged()` method of an `EditText` class: `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 Feb 28 '13 at 17:45
  • 22
    You may have to use et.post( new Runnable({... et.setSel... to get in the queue. This is because android waits to do some layout stuff until a better time by posting so if you try to setSelection before the system is finished it will undo your work. – MinceMan Dec 07 '13 at 18:16
  • 1
    It works here,thanks for your answer.But you should do like this: editText.setText(s); editText.setSelection(editText.getText().length()); //after setText – smileVann Mar 30 '14 at 15:10
  • Method name was not chosen wisely! not intuitive! – Ahmed Hegazy Feb 13 '18 at 17:17
235

There is a function called append for ediitext which appends the string value to current edittext value and places the cursor at the end of the value. You can have the string value as the current ediitext value itself and call append();

myedittext.append("current_this_edittext_string"); 
James
  • 13,095
  • 26
  • 65
  • 92
152

Kotlin:

set the cursor to the starting position:

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

set the cursor to the end of the EditText:

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

Below Code is to place the cursor after the second character:

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

JAVA:

set the cursor to the starting position:

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

set the cursor to the end of the EditText:

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

Below Code is to place the cursor after the second character:

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(2);
vovahost
  • 25,072
  • 12
  • 95
  • 99
Mr.vicky patel
  • 1,699
  • 1
  • 7
  • 18
  • 1
    Could replace `findViewById(R.id.edittext_id) as EditText` with `findViewById(R.id.edittext_id)` or just avoid the casting if using `API 26+` – Evin1_ Jun 25 '18 at 12:37
128

If you called setText before and the new text didn't get layout phase call setSelection in a separate runnable fired by View.post(Runnable) (repost from this topic).

So, for me this code works:

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

Edit 05/16/2019: Right now I'm using Kotlin extension for that:

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

and then - editText.placeCursorToEnd().

Lukas Niessen
  • 448
  • 3
  • 13
Anton Derevyanko
  • 3,241
  • 1
  • 22
  • 32
  • Thanks this really worked for me. I was trying to call setSelection but it won't work. In my case, I was trying to set a fixed prefix to edit text, and so after setting prefix, I needed to set the cursor to end of prefix so that user can enter data after the prefix. Since I was doing setSelection in constructor of a TextWatcher, may be thats why it did not work. But your solution worked great! – Wand Maker Sep 02 '13 at 08:33
  • I am using this post method in my MultiAutoCompleteTextView's Clickablespan method and it works.....I want the cursor to move at the end once the delete icon in the text span is clicked...It works in all the latest android mobiles...but in old versions it takes some time after the first click...all my other items does'nt become clickable...any clue?? – VijayRaj Sep 10 '13 at 07:29
  • 1
    I don't know why, but this is the only one that works for me! My edit text has a focus / text changed listener and is wrapped in a TextInputLayout. One of those things is messing it up. – Daniel Wilson May 20 '16 at 18:59
43

You could also place the cursor at the end of the text in the EditText view like this:

EditText et = (EditText)findViewById(R.id.textview);
int textLength = et.getText().length();
et.setSelection(textLength, textLength);
toobsco42
  • 6,131
  • 16
  • 73
  • 85
29
editText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        editText.setSelection(editText.getText().length());
        return false;
    }
});
kartikmaji
  • 916
  • 7
  • 21
Mario
  • 466
  • 4
  • 7
22

This is another possible solution:

et.append("");

Just try this solution if it doesn't work for any reason:

et.setSelection(et.getText().length());
Kreshnik
  • 2,201
  • 5
  • 28
  • 37
15

In my case I created the following kotlin ext. function, may be useful to someone

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

Then use as follows

mEditText.focus()
Igor Siqueira
  • 189
  • 1
  • 7
14

If your EditText is not clear:

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

or

editText.setText(null);
editText.append("New text");
Leo Droidcoder
  • 11,898
  • 3
  • 55
  • 48
13
/**
 * 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);

It work good for me!

Praxis Ashelin
  • 4,983
  • 2
  • 16
  • 43
Anh Duy
  • 1,004
  • 14
  • 21
13

You should be able to achieve that with the help of EditText's method setSelection(), see here

Rahul
  • 2,374
  • 2
  • 22
  • 36
Maximus
  • 8,061
  • 3
  • 27
  • 37
12

i think this can achieve what you want.

 Editable etext = mSubjectTextEditor.getText();
 Selection.setSelection(etext, etext.length());
Li Che
  • 719
  • 10
  • 23
  • If my observations are correct, this spawns an instance of android.widget.TextView$IClipboardDataPasteEventImpl for each widget. I ended up with tons of them. Apparently they get eventually cleaned up, but seem to drive up the memory consumption. I had 12 instances of one dialog, it's only dominator (whats keeping it alive) being the above mentioned instance. – AgentKnopf Jan 02 '13 at 12:02
  • Placing that piece of code at appropriate position in code (where you are appending text directly to EText). Thanks! – sud007 Jul 03 '17 at 13:58
10

The question is old and answered, but I think it may be useful to have this answer if you want to use the newly released DataBinding tools for Android, just set this in your XML :

<data>
    <variable name="stringValue" type="String"/>
</data>
...
<EditText
        ...
        android:text="@={stringValue}"
        android:selection="@{stringValue.length()}"
        ...
/>
djleop
  • 677
  • 4
  • 17
7

editText.setSelection is the magic here. Basically selection gives you place cursor at any position you want.

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

This places cursor to end of EditText. Basically editText.getText().length() gives you text length. Then you use setSelection with length.

editText.setSelection(0);

It is for setting cursor at start position (0).

Khemraj Sharma
  • 46,529
  • 18
  • 168
  • 182
7

enter image description here

Hello Try This

 <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
  • 123
  • 1
  • 5
6

This works

Editable etext = edittext.getText();
Selection.setSelection(etext,edittext.getText().toString().length());
Sk93
  • 3,494
  • 3
  • 33
  • 62
Hardik Vasani
  • 828
  • 1
  • 8
  • 13
5

If you want to select all text and just entering new text instead of old one, you can use

    android:selectAllOnFocus="true"
ar-g
  • 3,069
  • 2
  • 25
  • 34
4

All the other codes I've tested didn't work good due to the fact that the user could still place the caret/cursor wherever in the middle of the string (ex.: 12|3.00 - where | is the cursor). My solution always puts the cursor in the end of the string whenever the touch occurs on the EditText.

The ultimate solution is:

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

            }
        });

Hope it helps!

Daniel Almeida
  • 174
  • 1
  • 4
3

similar to @Anh Duy's answer, but it didnt work for me. i also needed the cursor to move to the end only when the user taps the edit text and still be able to select the position of the cursor afterwards, this is the only code that has worked for me

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;
    }
});
kartikmaji
  • 916
  • 7
  • 21
Fonix
  • 10,588
  • 2
  • 41
  • 67
3

This does the trick safely:

    editText.setText("");
    if (!TextUtils.isEmpty(text)) {
        editText.append(text);
    }
Alécio Carvalho
  • 12,697
  • 5
  • 63
  • 71
3
etSSID.setSelection(etSSID.getText().length());
adiga
  • 28,937
  • 7
  • 45
  • 66
3

For ViewModel, LiveData and Data binding

I needed this functionality for EditText with multiline support in my notes app. I wanted the cursor at the end of the text when the user navigates to the fragment that has note text.

The solution suggested by the djleop comes close. But the problem with this is that, if the user puts the cursor somewhere in the middle of the text for editing and starts typing, the cursor would jump to the end of text again. This happened because the LiveData would emit the new value and cursor would jump to the end of the text again resulting in user not able to edit the text somewhere in the middle.

To solve this, I use MediatorLiveData and assign it the length of String only once using a flag. This will cause the LiveData to read the value only once, that is, when the user navigates to the fragment. After that the user can place the cursor anywhere they want to edit the text there.

ViewModel

private var accessedPosition: Boolean = false

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

Here, yourObject is another LiveData retrieved from the database that holds the String text that you are displaying in the EditText.

Then bind this MediatorLiveData to your EditText using binding adapter.

XML

Uses two-way data binding for displaying text as well as accepting the text input.

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

Binding Adapter

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

Event class

The Event class here is like a SingleLiveEvent written by Jose Alcérreca from Google. I use it here to take care of screen rotation. Using the single Event will make sure that the cursor won't jump to the end of text when the user is editing the text somewhere in the middle and the screen rotates. It will maintain the same position when the screen rotates.

Here's the Event class:

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
}

This is the solution that works for me and provides good user experience. Hope it helps in your projects too.

Yogesh Umesh Vaity
  • 16,749
  • 10
  • 82
  • 69
3

The above answers didnt worked for me. So i found out a new solution. This maybe helpful to someone. I have been using the latest version of Android Studio i.e 3.5 as per the present date. Maybe that might be the reason y the above answers didnt showed any effect.

CODE:

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

Here, the 1st argument is the Spannable text value that you want to playwith whereas the 2nd argument is the index value. Since, we want the cursor at the end of the text, we took getText().length() which returns the length of the text

Prajwal Waingankar
  • 1,922
  • 2
  • 8
  • 14
2
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) {

    }
}

User this CustomEditText in your XML file, this will work. I have tested this and it is working for me.

kishna.147
  • 167
  • 8
2

If you want to Place cursor at the end of text in EditText view

 EditText rename;
 String title = "title_goes_here";
 int counts = (int) title.length();
 rename.setSelection(counts);
 rename.setText(title);
Mujahid Khan
  • 925
  • 1
  • 12
  • 19