EditText'te imleci metnin sonuna getir


883

Bir değerini değiştirerek am EditTexttarihinde adlı keyListener.

Ama metni değiştirdiğimde imleç EditText. İmlecin metnin sonunda olması lazım.

İmleci a metninin sonuna taşıma EditText.


3
Aynı sorunla karşılaştım. Ama kendime daha iyi sorduğum şey, bunun neden olduğunu, böylece sorunu kendim taşımak zorunda kalmadan daha önce çözebilmem için oldu.
kaneda

3
@kaneda Kesinlikle katılıyorum, ancak asıl çözümü ekleseydiniz faydalı olurdu.
AgentKnopf

1
@Zainodis Bu sadece bir düşünceliydi. Dediğim gibi aynı sorunla karşılaştım, bu da çözümü bulduğum anlamına gelmiyor. Benim durumumda bir EditTexts öğeleri olarak sorunu vardı ListView. Deneylere gelince, ListViewoldukça karmaşık bir canavar olan kaynak kodun kendisinde bazı değişiklikler yaptım ve emülatörde test ettim . Bileşen tarafından yapılan odak kontrol yönetimi ile ilgiliydi. Bu yüzden elbette arkadaşımıza yardım etmek için verebileceğim bir çözüm değil. :)
kaneda


Bu OnFocusChangedgeri arama içinde çalışmaz . Burada çözüm setSelection'ı çalıştırılabilir bir kabın içine koymak ve ana iplik üzerinde çalıştırmaktır. Buradan kontrol edin stackoverflow.com/a/32156989/4514796
Ali Nem

Yanıtlar:


1318

Bunu dene:

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

15
Bu benim durumumda çalışmıyor. SetSelection () yönteminin bir etkisi yok gibi görünüyor. EditText görünümüm ImageSpans içeriyor. Başka bir geçici çözüm var mı?
toobsco42

@marqss, ben aynı sorunu vardı ve benim için mükemmel çalıştı. Bir Dialog üzerinde EditText kullanıyordum ve ana ekrandan metni önceden dolduruyordum. Bu olduğunda imleç başlangıçta kalıyordu, sonunda değil ama önerinizi denedikten sonra her şey yolunda, istediğim gibi. Bunu gönderdiğiniz için teşekkür ederiz.
Vincy

4
Hey @Mullay, şimdi onSelectionChanged()bir EditTextsınıf yöntemini geçersiz kılarak ele 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); }
alıyorum

19
Kuyruğa girmek için et.post (yeni Runnable ({... et.setSel ...) kullanmanız gerekebilir. Bunun nedeni, android'in yayınlamaya çalışarak daha iyi bir zamana kadar bazı düzen şeyleri yapmayı beklemesidir. sistem bitmeden önce işinizi geri alır
MinceMan

1
Burada çalışıyor, cevabınız için teşekkürler.Ama bunu yapmalısınız: editText.setText (s); editText.setSelection (editText.getText () uzunluğu ().); // sonra setText
smileVann

223

Dize değerini geçerli düzenleme metni değerine ekleyen ve imleci değerin sonuna yerleştiren ediitext için append adında bir işlev vardır. Dize değerini geçerli ediitext değerinin kendisi olarak alabilir ve append () öğesini çağırabilirsiniz;

myedittext.append("current_this_edittext_string"); 

1
EditText'inizde zaten metin varsa, şunu yazınmyedittext.append("");
ymerdrengene

4
@ymerdrengene sadece başvuru myedittext.append("");benim için işe yaramadı!
Chintan Shah

4
Bu mükemmel çünkü sadece sahip olduğum kod satırının yerini alıyor. Edittextfield.setText kullanıyordum ve sadece eklemek için değiştirdim. Çok basit.
theblitz

İşe yarayıp yaramadığına bağlı olarak kullanıma bağlıdır. Benim için olmadı. Kullanmak Selectiono IMO'ya ulaşmanın doğru yoludur.
sud007

139

Kotlin :

imleci başlangıç ​​konumuna getirin :

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

imleci EditText öğesinin sonuna getirin :

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

Aşağıdaki Kod, imleci ikinci karakterden sonra yerleştirmektir:

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

JAVA :

imleci başlangıç ​​konumuna getirin :

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

imleci EditText öğesinin sonuna getirin :

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

Aşağıdaki Kod, imleci ikinci karakterden sonra yerleştirmektir:

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

1
Yerine Could findViewById(R.id.edittext_id) as EditTextile findViewById<EditText>(R.id.edittext_id)ya da sadece kullanılıyorsa dökümü kaçınınAPI 26+
Evin1_

97

Daha setTextönce çağırdıysanız ve yeni metin setSelectiontarafından düzenlenmiş ayrı bir çalıştırılabilir düzen aşaması çağrısı almadıysanız View.post(Runnable)( bu konuyu yeniden gönder ).

Yani, benim için bu kod çalışıyor:

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

Edit 05/16/2019: Şu anda bunun için Kotlin eklentisini kullanıyorum:

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

ve sonra - editText.placeCursorToEnd ().


Teşekkürler bu gerçekten benim için çalıştı. SetSelection'ı aramaya çalışıyordum ama işe yaramayacak. Benim durumumda, metni düzenlemek için sabit bir önek ayarlamaya çalışıyordum ve bu nedenle öneki ayarladıktan sonra, kullanıcının önekten sonra veri girebilmesi için imleci önek sonuna ayarlamam gerekiyordu. Bir TextWatcher'ın yapıcısında setSelection yaptığım için, bu neden işe yaramadı. Ancak çözümünüz harika çalıştı!
Wand Maker

Benim MultiAutoCompleteTextView Clickablespan yönteminde bu yazı yöntemini kullanıyorum ve çalışıyor ..... Metin yayılma alanındaki silme simgesi tıklatıldığında imlecin sonunda hareket etmesini istiyorum ... En son android cep telefonlarında çalışır. ..ama eski sürümlerde ilk tıklamadan sonra biraz zaman alır ... diğer tüm öğelerim tıklanabilir hale gelmez ... herhangi bir ipucu ??
VijayRaj

1
Nedenini bilmiyorum, ama bu benim için çalışan tek kişi! Düzenleme metnimde odak / metin değiştirilmiş dinleyici var ve TextInputLayout içine sarılmış. Bunlardan biri onu mahvediyor.
Daniel Wilson

42

İmleci EditTextgörünümdeki metnin sonuna şu şekilde de yerleştirebilirsiniz :

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

Bu başka bir olası çözümdür:

et.append("");

Herhangi bir nedenle çalışmazsa bu çözümü deneyin:

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);

Benim için iyi çalışıyor!


12

Benim durumumda aşağıdaki kotlin ext. işlevi, birisi için yararlı olabilir

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

Sonra aşağıdaki gibi kullanın

mEditText.focus()

12

EditText'iniz net değilse:

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

veya

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

12

Bunu EditText'syöntem yardımıyla başarabilmelisiniz setSelection(), buraya bakın


10

bence bu istediğini başarabilir.

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

Gözlemlerim doğruysa, bu her widget için android.widget.TextView $ IClipboardDataPasteEventImpl örneğini oluşturur. Sonunda tonlarca aldım. Görünüşe göre sonunda temizleniyorlar, ancak bellek tüketimini artırıyor gibi görünüyorlar. Bir diyalogun 12 örneği vardı, sadece yukarıda belirtilen örnek olan dominator (onu canlı tutuyor).
AgentKnopf

Bu kod parçasını kod içinde uygun bir konuma yerleştirme (metni doğrudan EText'e eklediğiniz yerde). Teşekkürler!
sud007

9

Soru eski ve cevaplandı, ancak Android için yeni yayınlanan DataBinding araçlarını kullanmak istiyorsanız, bu cevabı almanın yararlı olabileceğini düşünüyorum, sadece XML'inizde ayarlayın:

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

6

resim açıklamasını buraya girin

Merhaba Bunu Deneyin

 <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 pointkürsör


5

Tüm metni seçmek ve eskisi yerine yeni metin girmek istiyorsanız,

    android:selectAllOnFocus="true"

5

Bu çalışıyor

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

5

editText.setSelectionburadaki sihir. Temel olarak seçim, imleci istediğiniz konuma getirmenizi sağlar.

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

Bu, imleci EditText öğesinin sonuna yerleştirir. Temel olarak editText.getText().length()size metin uzunluğu verir. Sonra setSelectionuzunluk ile kullanın .

editText.setSelection(0);

İmleci başlangıç ​​konumuna ayarlamak içindir (0).


4

Test ettiğim diğer tüm kodlar, kullanıcının hala imleci / imleci dizenin ortasına yerleştirebilmesi nedeniyle iyi çalışmadı (örneğin: 12 | 3.00 - burada | imleç). Çözümüm, EditText'te dokunma gerçekleştiğinde her zaman imleci dizenin sonuna koyar.

Nihai çözüm:

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

            }
        });

Umarım yardımcı olur!


3

ViewModel, LiveData ve Data bağlama için

EditTextNotlar uygulamamda çok satırlı destek için bu işlevselliğe ihtiyacım vardı . Kullanıcı not metni olan parçaya gittiğinde imlecin metnin sonunda olmasını istedim.

Djleop tarafından önerilen çözüm yaklaşıyor. Ancak bununla ilgili sorun, kullanıcı imleci düzenleme için metnin ortasına yerleştirir ve yazmaya başlarsa, imlecin metnin sonuna tekrar atlamasıdır. Bunun nedeni, LiveDatayeni değeri yayacağı ve imlecin metnin sonuna atlayacağı ve kullanıcının metni ortada bir yerde düzenleyememesine neden olacağı için oldu.

Bunu çözmek için kullandığım MediatorLiveDatave bu uzunluğunu atamak Stringbir bayrak kullanarak yalnızca bir kez. Bu, LiveData'nın değeri yalnızca bir kez, yani kullanıcı parçaya gittiğinde okumasına neden olur. Bundan sonra kullanıcı imleci oradaki metni düzenlemek istediği herhangi bir yere yerleştirebilir.

ViewModel

private var accessedPosition: Boolean = false

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

Burada, yourObjectgörüntülediğiniz Dize metnini tutan veritabanından alınan başka bir LiveData EditText.

Ardından MediatorLiveData, ciltleme bağdaştırıcısını kullanarak bunu EditText'inize bağlayın.

XML

Metni görüntülemek ve metin girişini kabul etmek için iki yönlü veri bağlama kullanır.

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

Ciltleme Adaptörü

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

Event sınıf

Buradaki Eventsınıf , Google'dan Jose Alcérreca tarafından yazılmış bir SingleLiveEvent gibidir . Burada ekran döndürme ile ilgilenmek için kullanıyorum. Single'ı kullanmak, Eventkullanıcı metni ortada bir yerde düzenlerken ve ekran döndüğünde imlecin metnin sonuna atlamamasını sağlar. Ekran döndüğünde aynı konumu koruyacaktır.

İşte Eventsınıf:

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
}

Bu benim için çalışan ve iyi bir kullanıcı deneyimi sağlayan bir çözümdür. Umarım projelerinize de yardımcı olur.


Bu cevabın daha yukarıda olması gerekiyor. Çok teşekkürler
Abdul Rahman Shamair

2

@Anh Duy'un cevabına benzer, ama benim için işe yaramadı. Ayrıca sadece kullanıcı düzenleme metnine dokunduğunda ve daha sonra imlecin konumunu seçebildiğinde imlecin sonuna kadar hareket etmesi gerekiyordu, bu benim için çalışan tek kod

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

Bu hile güvenli bir şekilde yapar :

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


2

Yukarıdaki cevaplar benim için işe yaramadı. Böylece yeni bir çözüm buldum. Bu belki birisi için yararlı olabilir. Şu anki tarihe göre Android Studio'nun en son sürümünü yani 3.5 kullanıyorum. Belki de yukarıdaki cevapların herhangi bir etki göstermemesinin nedeni bu olabilir.

KODU:

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

Burada, birinci argüman oynatmak istediğiniz Spannable metin değeridir, ikinci argüman ise dizin değeridir. İmleci metnin sonunda istediğimizden, metnin uzunluğunu döndüren getText (). Length () yöntemini aldık


1
Zevkle! Mutlu Kodlama!
Prajwal K

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

    }
}

XML dosyanızda bu CustomEditText kullanıcısı, bu işe yarayacak. Bunu test ettim ve benim için çalışıyor.


1

EditText görünümünde metnin sonuna imleci yerleştirmek istiyorsanız

 EditText rename;
 String title = "title_goes_here";
 int counts = (int) title.length();
 rename.setSelection(counts);
 rename.setText(title);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.