Tempatkan kursor di akhir teks dalam EditText

883

Saya mengubah nilai EditTexton keyListener.

Tetapi ketika saya mengubah teks kursor bergerak ke awal EditText. Saya perlu kursor berada di akhir teks.

Cara memindahkan kursor ke akhir teks dalam a EditText.

Manu
sumber
3
Saya menemukan masalah yang sama. Tapi yang saya tanyakan pada diri saya lebih baik adalah mengapa hal ini terjadi, sehingga saya bisa menyelesaikan masalah sebelumnya daripada harus memindahkan caret sendiri.
kaneda
3
@kaneda Saya sangat setuju, namun akan sangat membantu jika Anda telah menambahkan solusi yang sebenarnya.
AgentKnopf
1
@ Zainodis Itu hanya sebuah pemikiran. Seperti yang saya katakan, saya menemukan masalah yang sama, yang tidak berarti saya telah menemukan solusinya. Dalam kasus saya, saya memiliki masalah dengan EditTexts sebagai item dari a ListView. Adapun eksperimen, saya membuat beberapa perubahan pada ListViewkode sumber itu sendiri, yang merupakan binatang yang agak kompleks, dan diuji pada emulator. Itu terkait dengan manajemen kontrol fokus yang dibuat oleh komponen. Jadi tentu saja itu bukan solusi yang bisa saya berikan untuk membantu teman kita. :)
kaneda
2
kemungkinan rangkap dari edittext Android - masalah kursor
settextmethod
Ini tidak berfungsi di dalam OnFocusChangedpanggilan balik. Solusinya adalah menempatkan setSelection di dalam runnable dan menjalankannya di utas utama. Lihat di sini stackoverflow.com/a/32156989/4514796
Ali Nem

Jawaban:

1319

Coba ini:

EditText et = (EditText)findViewById(R.id.inbox);
et.setSelection(et.getText().length());
Marqs
sumber
15
Ini tidak berfungsi dalam kasus saya. Metode setSelection () tampaknya tidak berpengaruh. Tampilan EditText saya berisi ImageSpans. Apakah ada solusi lain?
toobsco42
@marqss, saya memiliki masalah yang sama dan bekerja dengan baik untuk saya. Saya menggunakan EditText pada Dialog dan pra-mengisi teks dari layar utama. Ketika itu terjadi, kursor tetap berada di awal dan tidak di akhir tetapi setelah saya mencoba saran Anda semuanya baik-baik saja, seperti yang saya inginkan. Terima kasih telah memposting ini.
Vincy
4
Hey @Mullay, saya sekarang menanganinya dengan mengesampingkan onSelectionChanged()metode EditTextkelas: 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
Anda mungkin harus menggunakan et.post (Runnable baru ({... et.setSel ... untuk masuk dalam antrian. Ini karena android menunggu untuk melakukan beberapa hal tata letak hingga waktu yang lebih baik dengan memposting jadi jika Anda mencoba mengaturSelection sebelum sistem selesai, ini akan membatalkan pekerjaan Anda
MinceMan
1
Ini berfungsi di sini, terima kasih atas jawaban Anda. Tetapi Anda harus melakukannya seperti ini: editText.setText; editText.setSelection (editText.getText (). length ()); // setelah setText
smileVann
224

Ada fungsi yang disebut append for ediitext yang menambahkan nilai string ke nilai edittext saat ini dan menempatkan kursor di akhir nilai. Anda dapat memiliki nilai string sebagai nilai ediitext saat itu sendiri dan memanggil append ();

myedittext.append("current_this_edittext_string"); 
James
sumber
1
Jika Anda sudah memiliki teks di EditText Anda, cukup tulismyedittext.append("");
ymerdrengene
4
@ymerdrengene hanya melamar myedittext.append("");tidak berhasil untuk saya!
Chintan Shah
4
Ini sempurna karena hanya mengganti baris kode yang saya miliki. Menggunakan edittextfield.setText dan baru saja menukarnya dengan append. Sangat sederhana.
theblitz
Tergantung penggunaannya apakah itu berfungsi atau tidak. Bagi saya tidak. Menggunakan Selectioncara yang benar untuk mencapai IMO itu.
sud007
140

Kotlin :

atur kursor ke posisi awal :

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

setel kursor ke akhir EditText :

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

Kode di bawah ini untuk menempatkan kursor setelah karakter kedua:

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

JAWA :

atur kursor ke posisi awal :

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

setel kursor ke akhir EditText :

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

Kode di bawah ini untuk menempatkan kursor setelah karakter kedua:

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(2);
Mr.vicky patel
sumber
1
Bisa mengganti findViewById(R.id.edittext_id) as EditTextdengan findViewById<EditText>(R.id.edittext_id)atau hanya menghindari casting jika menggunakanAPI 26+
Evin1_
97

Jika Anda menelepon setTextsebelumnya dan teks baru tidak mendapatkan panggilan fase tata letak setSelectiondi runnable terpisah yang dipecat oleh View.post(Runnable)(repost dari topik ini ).

Jadi, bagi saya kode ini berfungsi:

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

Sunting 05/16/2019: Saat ini saya sedang menggunakan ekstensi Kotlin untuk itu:

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

dan kemudian - editText.placeCursorToEnd ().

Anton Derevyanko
sumber
Terima kasih, ini benar-benar berhasil untuk saya. Saya mencoba memanggil setSelection tetapi tidak berhasil. Dalam kasus saya, saya mencoba untuk mengatur awalan tetap untuk mengedit teks, dan jadi setelah mengatur awalan, saya perlu mengatur kursor ke akhir awalan sehingga pengguna dapat memasukkan data setelah awalan. Karena saya sedang melakukan setSelection dalam konstruktor dari TextWatcher, mungkin itulah sebabnya tidak berhasil. Tapi solusi Anda berhasil!
Wand Maker
Saya menggunakan metode posting ini di metode Clickablespan MultiAutoCompleteTextView saya dan berfungsi ..... Saya ingin kursor bergerak di akhir begitu ikon hapus dalam rentang teks diklik ... Ini berfungsi di semua ponsel android terbaru. ..tapi dalam versi lama butuh beberapa saat setelah klik pertama ... semua item saya yang lain tidak dapat diklik ... petunjuk apa saja ??
VijayRaj
1
Saya tidak tahu mengapa, tetapi ini adalah satu-satunya yang bekerja untuk saya! Teks edit saya memiliki fokus / teks yang diubah pendengar dan dibungkus dengan TextInputLayout. Salah satunya adalah mengacaukannya.
Daniel Wilson
42

Anda juga bisa menempatkan kursor di akhir teks dalam EditTexttampilan seperti ini:

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

Ini adalah solusi lain yang mungkin:

et.append("");

Coba saja solusi ini jika tidak berhasil karena alasan apa pun:

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

Ini bekerja baik untuk saya!

Anh Duy
sumber
12

Dalam kasus saya, saya membuat ext kotlin berikut. fungsinya, semoga bermanfaat bagi seseorang

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

Kemudian gunakan sebagai berikut

mEditText.focus()
Igor Siqueira
sumber
12

Jika EditText Anda tidak jelas:

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

atau

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

Anda harus dapat mencapainya dengan bantuan EditText'smetode setSelection(), lihat di sini

Maximus
sumber
10

Saya pikir ini dapat mencapai apa yang Anda inginkan.

 Editable etext = mSubjectTextEditor.getText();
 Selection.setSelection(etext, etext.length());
Li Che
sumber
Jika pengamatan saya benar, ini memunculkan instance dari android.widget.TextView $ IClipboardDataPasteEventImpl untuk setiap widget. Saya berakhir dengan banyak dari mereka. Tampaknya mereka akhirnya dibersihkan, tetapi tampaknya menaikkan konsumsi memori. Saya punya 12 contoh dari satu dialog, itu hanya dominator (apa yang membuatnya tetap hidup) menjadi contoh yang disebutkan di atas.
AgentKnopf
Menempatkan potongan kode pada posisi yang sesuai dalam kode (di mana Anda menambahkan teks langsung ke EText). Terima kasih!
sud007
9

Pertanyaannya sudah lama dan dijawab, tetapi saya pikir mungkin ada manfaatnya untuk memiliki jawaban ini jika Anda ingin menggunakan alat DataBinding yang baru dirilis untuk Android, cukup tetapkan ini di XML Anda:

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

masukkan deskripsi gambar di sini

Halo, Coba Ini

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

Rahul Patil
sumber
5

Jika Anda ingin memilih semua teks dan hanya memasukkan teks baru alih-alih yang lama, Anda dapat menggunakannya

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

Ini bekerja

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

editText.setSelectionadalah keajaiban di sini. Pada dasarnya pemilihan memberi Anda menempatkan kursor pada posisi apa pun yang Anda inginkan.

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

Ini menempatkan kursor ke akhir EditText. Pada dasarnya editText.getText().length()memberi Anda panjang teks. Kemudian Anda gunakan setSelectiondengan panjang.

editText.setSelection(0);

Ini untuk mengatur kursor pada posisi awal (0).

Khemraj
sumber
4

Semua kode lain yang saya uji tidak bekerja dengan baik karena fakta bahwa pengguna masih dapat menempatkan tanda sisipan / kursor di mana pun di tengah-tengah string (mis .: 12 | 3.00 - di mana | adalah kursor). Solusi saya selalu menempatkan kursor di akhir string setiap kali ada sentuhan pada EditText.

Solusi utamanya adalah:

// 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 / jumlah = "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) {

            }
        });

Semoga ini bisa membantu!

Daniel Almeida
sumber
3

Untuk ViewModel, LiveData, dan Data binding

Saya membutuhkan fungsi ini untuk EditTextdengan dukungan multiline di aplikasi catatan saya. Saya ingin kursor di akhir teks ketika pengguna menavigasi ke fragmen yang memiliki teks catatan.

Solusi yang disarankan oleh djleop datang mendekat. Tetapi masalah dengan ini adalah bahwa, jika pengguna meletakkan kursor di suatu tempat di tengah teks untuk mengedit dan mulai mengetik, kursor akan melompat ke ujung teks lagi. Ini terjadi karena LiveDataakan memancarkan nilai baru dan kursor akan melompat ke ujung teks lagi sehingga pengguna tidak dapat mengedit teks di suatu tempat di tengah.

Untuk mengatasi ini, saya menggunakan MediatorLiveDatadan menetapkan panjang Stringhanya sekali menggunakan bendera. Ini akan menyebabkan LiveData membaca nilai hanya sekali, yaitu ketika pengguna menavigasi ke fragmen. Setelah itu pengguna dapat menempatkan kursor di mana saja mereka ingin mengedit teks di sana.

ViewModel

private var accessedPosition: Boolean = false

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

Di sini, yourObjectadalah LiveData lain yang diambil dari database yang menyimpan teks String yang Anda tampilkan di EditText.

Kemudian ikat ini MediatorLiveDatake EditText Anda menggunakan adaptor yang mengikat.

XML

Menggunakan pengikatan data dua arah untuk menampilkan teks serta menerima input teks.

<!-- 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 kelas

The Eventkelas di sini adalah seperti SingleLiveEvent ditulis oleh Jose Alcérreca dari Google. Saya menggunakannya di sini untuk menjaga rotasi layar. Menggunakan single Eventakan memastikan bahwa kursor tidak akan melompat ke akhir teks ketika pengguna mengedit teks di suatu tempat di tengah dan layar berputar. Ini akan mempertahankan posisi yang sama ketika layar berputar.

Inilah Eventkelasnya:

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
}

Ini adalah solusi yang berfungsi untuk saya dan memberikan pengalaman pengguna yang baik. Semoga ini membantu dalam proyek Anda juga.

Yogesh Umesh Vaity
sumber
Jawaban ini perlu ditingkatkan. Terima Kasih Banyak
Abdul Rahman Shamair
2

mirip dengan jawaban @Anh Duy, tetapi tidak berhasil untuk saya. saya juga membutuhkan kursor untuk pindah ke ujung hanya ketika pengguna mengetuk teks edit dan masih dapat memilih posisi kursor setelah itu, ini adalah satu-satunya kode yang bekerja untuk saya

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
sumber
2

Ini melakukan trik dengan aman :

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

Jawaban di atas tidak berhasil untuk saya. Jadi saya menemukan solusi baru. Ini mungkin membantu seseorang. Saya telah menggunakan versi terbaru Android Studio yaitu 3,5 sesuai tanggal sekarang. Mungkin itu mungkin alasan mengapa jawaban di atas tidak menunjukkan efek apa pun.

KODE:

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

Di sini, argumen 1 adalah nilai teks Spannable yang ingin Anda mainkan sedangkan argumen ke-2 adalah nilai indeks. Karena, kami ingin kursor di akhir teks, kami mengambil getText (). Length () yang mengembalikan panjang teks

Prajwal W
sumber
1
Dengan senang hati! Selamat Coding!
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) {

    }
}

Gunakan CustomEditText ini dalam file XML Anda, ini akan berfungsi. Saya telah menguji ini dan itu berfungsi untuk saya.

kishna.147
sumber
1

Jika Anda ingin menempatkan kursor di akhir teks dalam tampilan EditText

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