EditText에서 텍스트 끝에 커서를 놓습니다.


883

나는의 값을 변경하고 EditText의를 keyListener.

그러나 텍스트를 변경하면 커서가 시작 부분으로 이동합니다 EditText. 텍스트 끝에 커서가 있어야합니다.

어떻게 텍스트의 끝으로 커서를 이동합니다 EditText.


3
나는 같은 문제를 겪었다. 그러나 내가 더 잘한 것은 왜 이런 일이 일어나고 있는지, 그래서 캐럿을 직접 옮기지 않고 이전에 문제를 해결할 수 있다는 것입니다.
kaneda

3
@kaneda 전적으로 동의하지만 실제 솔루션을 추가하면 도움이 될 것입니다.
Agent Knopf

1
@Zainodis 그것은 단지 생각이었다. 내가 말했듯이 동일한 문제가 발생했다고해서 반드시 해결책을 찾았다는 것을 의미하지는 않습니다. 내 경우에는 EditText의 항목으로 s에 문제가있었습니다 ListView. 실험에 관해서는 ListView소스 코드 자체를 약간 변경 했는데, 이는 다소 복잡한 짐승이며 에뮬레이터에서 테스트되었습니다. 컴포넌트에 의한 포커스 제어 관리와 관련이 있습니다. 물론 친구를 도울 수있는 해결책은 아닙니다. :)
kaneda 2019 년


OnFocusChanged콜백 에서는 작동하지 않습니다 . 해결책은 setSelection을 실행 가능 파일에 넣고 기본 스레드에서 실행하는 것입니다. 여기를 확인하십시오 stackoverflow.com/a/32156989/4514796
Ali Nem

답변:


1318

이 시도:

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

15
내 경우에는 작동하지 않습니다. setSelection () 메소드가 효과가없는 것 같습니다. 내 EditText보기에 ImageSpans가 포함되어 있습니다. 다른 종류의 해결 방법이 있습니까?
toobsco42

@ marqss, 나는 같은 문제가 있었고 나를 위해 완벽하게 일했습니다. 대화 상자에서 EditText를 사용하고 기본 화면에서 텍스트를 미리 채웠습니다. 그 일이 발생하면 커서는 처음이 아닌 끝 부분에 머물 렀지 만 제안을 시도한 후 모든 것이 잘되었습니다. 이것을 게시 해 주셔서 감사합니다.
Vincy

4
@Mullay 님, 저는 이제 클래스 의 onSelectionChanged()메소드를 재정 의하여 처리하고 있습니다 EditText: 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
대기열에 들어가려면 et.post (new Runnable ({... et.setSel ...)을 사용해야 할 수도 있습니다. 이는 안드로이드가 게시를 통해 더 나은 시간까지 레이아웃 작업을 대기하기 때문에 setSelection을 시도하면 시스템이 완료되기 전에 작업이 취소됩니다
MinceMan

1
그것은 당신의 대답에 감사합니다. 그러나 당신은 다음과 같이해야합니다 : editText.setText (s); editText.setSelection (editText.getText (). length ()); // setText 이후
smileVann

223

문자열 값을 현재 edittext 값에 추가하고 커서를 값의 끝에 놓는 ediitext에 대한 append라는 함수가 있습니다. 문자열 값을 현재 ediitext 값으로 사용하고 append ()를 호출 할 수 있습니다.

myedittext.append("current_this_edittext_string"); 

1
EditText에 이미 텍스트가 있다면, 다음과 같이 작성하십시오myedittext.append("");
ymerdrengene

4
@ymerdrengene이 적용 myedittext.append("");되지 않았습니다.
Chintan Shah

4
이것은 내가 가진 코드 줄을 단순히 대체하기 때문에 완벽합니다. edittextfield.setText를 사용하고 있었고 추가하기 위해 스왑했습니다. 매우 간단합니다.
theblitz

작동 여부에 따라 사용법에 따라 다릅니다. 나를 위해 그것은하지 않았다. 사용은 SelectionIMO 그 달성의 올바른 방법입니다.
sud007

139

코 틀린 :

커서를 시작 위치 로 설정하십시오 .

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

커서를 EditText끝으로 설정하십시오 .

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

아래 코드는 두 번째 문자 뒤에 커서를 놓는 것입니다 .

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

자바 :

커서를 시작 위치 로 설정하십시오 .

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

커서를 EditText끝으로 설정하십시오 .

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

아래 코드는 두 번째 문자 뒤에 커서를 놓는 것입니다 .

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

1
대체 할 수 findViewById(R.id.edittext_id) as EditText와 함께 findViewById<EditText>(R.id.edittext_id)하거나 사용하는 경우 캐스팅을 피하기API 26+
Evin1_

96

당신은 호출하면 setText이전과 새로운 텍스트의 위상 호출을 배치하지 않았다 setSelection별도의 실행 가능한가에 의해 해고에 View.post(Runnable)(에서 재 게시 주제).

그래서 나를 위해이 코드는 작동합니다 :

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

편집 05/16/2019 : 현재 Kotlin 확장을 사용하고 있습니다.

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

그런 다음-editText.placeCursorToEnd ().


고마워 이것은 정말로 나를 위해 일했습니다. setSelection을 호출하려고 시도했지만 작동하지 않습니다. 필자의 경우 텍스트를 편집하기 위해 고정 접두사를 설정하려고 시도했기 때문에 접두사를 설정 한 후 사용자가 접두사 뒤에 데이터를 입력 할 수 있도록 커서를 접두사 끝으로 설정해야했습니다. TextWatcher의 생성자에서 setSelection을 수행했기 때문에 작동하지 않을 수 있습니다. 그러나 귀하의 솔루션은 훌륭하게 작동했습니다!
완드 메이커

내 MultiAutoCompleteTextView의 Clickablespan 메소드 에서이 post 메소드를 사용하고 있으며 작동합니다 ..... 텍스트 범위의 삭제 아이콘을 클릭하면 커서가 끝에서 움직이기를 원합니다 ... 모든 최신 안드로이드 모바일에서 작동합니다. ..하지만 이전 버전에서는 첫 번째 클릭 후 시간이 걸립니다 ... 다른 모든 항목은 클릭 할 수 없게됩니다.
VijayRaj

1
나는 왜 그런지 모르겠지만 이것이 나를 위해 일하는 유일한 것입니다! 내 편집 텍스트에는 포커스 / 텍스트 변경 리스너가 있으며 TextInputLayout에 래핑됩니다. 그중 하나가 엉망입니다.
Daniel Wilson

42

다음 EditText과 같이 뷰 의 텍스트 끝에 커서를 놓을 수도 있습니다 .

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

이것은 또 다른 가능한 해결책입니다.

et.append("");

어떤 이유로 든 작동하지 않으면이 솔루션을 사용해보십시오.

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

그것은 나를 위해 잘 작동합니다!


12

내 경우에는 다음과 같은 kotlin ext를 만들었습니다. 기능, 누군가에게 유용 할 수 있습니다

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

다음과 같이 사용하십시오

mEditText.focus()

12

EditText가 명확하지 않은 경우 :

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

또는

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


10

나는 이것이 당신이 원하는 것을 성취 할 수 있다고 생각합니다.

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

내 관측치가 정확하면 각 위젯에 대해 android.widget.TextView $ IClipboardDataPasteEventImpl 인스턴스가 생성됩니다. 나는 그들의 톤으로 끝났다. 분명히 그들은 결국 정리되지만 메모리 소비를 늘리는 것처럼 보입니다. 나는 하나의 대화 상자의 12 인스턴스를 가지고 있었고, 위에서 언급 한 인스턴스 인 유일한 지배자 (생존하는 것)입니다.
AgentKnopf

해당 코드 조각을 코드에서 적절한 위치에 배치하십시오 (텍스트를 EText에 직접 추가하는 위치). 감사!
sud007

9

이 질문은 오래되어 답변되었지만 새로 출시 된 Android 용 DataBinding 도구를 사용하려면이 답변을 얻는 것이 유용 할 수 있다고 생각합니다 .XML로 설정하십시오.

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

6

여기에 이미지 설명을 입력하십시오

안녕하세요 시도

 <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 point커서


5

모든 텍스트를 선택하고 이전 텍스트 대신 새 텍스트를 입력하려는 경우

    android:selectAllOnFocus="true"

5

이 작동합니다

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

5

editText.setSelection여기 마법이 있습니다. 기본적으로 선택하면 원하는 위치에 커서를 놓을 수 있습니다.

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

커서가 EditText의 끝에 위치합니다. 기본적으로 editText.getText().length()텍스트 길이를 제공합니다. 그런 다음 setSelection길이와 함께 사용하십시오 .

editText.setSelection(0);

시작 위치 (0)에서 커서를 설정하기위한 것입니다.


4

내가 테스트 한 다른 모든 코드는 사용자가 문자열의 중앙에 캐럿 / 커서를 배치 할 수 있다는 사실 때문에 잘 작동하지 않았습니다 (예 : 12 | 3.00-여기서 |는 커서입니다). 내 솔루션은 EditText에서 터치가 발생할 때마다 항상 문자열 끝에 커서를 놓습니다.

궁극적 인 해결책은 다음과 같습니다.

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

            }
        });

그것이 도움이되기를 바랍니다!


3

ViewModel, LiveData 및 데이터 바인딩

EditText노트 앱에서 여러 줄을 지원 하기 위해이 기능이 필요했습니다 . 사용자가 메모 텍스트가있는 조각으로 이동할 때 텍스트 끝에 커서를 원했습니다.

djleop 이 제안한 솔루션 이 가깝습니다. 그러나 이것의 문제점은 사용자가 편집을 위해 텍스트 중간에 커서를 놓고 입력을 시작하면 커서가 텍스트의 끝으로 다시 이동한다는 것입니다. 이것은 LiveData새로운 값을 내고 커서가 텍스트의 끝으로 다시 이동하여 사용자가 텍스트를 중간에 편집 할 수 없기 때문에 발생했습니다.

이를 해결하기 위해 플래그를 사용하여 한 번만 MediatorLiveData길이를 할당하고 할당합니다 String. 이로 인해 LiveData는 값을 한 번만, 즉 사용자가 조각을 탐색 할 때 값을 읽습니다. 그 후 사용자는 텍스트를 편집하려는 위치에 커서를 놓을 수 있습니다.

뷰 모델

private var accessedPosition: Boolean = false

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

여기 yourObject에 표시되는 문자열 텍스트를 보유하는 데이터베이스에서 검색된 다른 LiveData가 있습니다 EditText.

그런 다음 MediatorLiveData바인딩 어댑터를 사용하여 이것을 EditText에 바인딩하십시오.

XML

텍스트를 표시하고 텍스트 입력을 수락하기 위해 양방향 데이터 바인딩을 사용합니다.

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

바인딩 어댑터

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

Event 수업

Event수업 은 Google의 Jose Alcérreca가 작성한 SingleLiveEvent 와 같습니다 . 화면 회전을 관리하기 위해 여기에서 사용합니다. 싱글 Event을 사용하면 사용자가 텍스트를 중간 위치에서 편집하고 화면이 회전 할 때 커서가 텍스트 끝으로 이동하지 않습니다. 화면이 회전 할 때 동일한 위치를 유지합니다.

Event수업 은 다음과 같습니다 .

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
}

이것은 저에게 효과적이며 우수한 사용자 경험을 제공하는 솔루션입니다. 그것이 당신의 프로젝트에도 도움이되기를 바랍니다.


이 답변은 나아갈 필요가 있습니다. 많은 감사
Abdul Rahman Shamair

2

@Anh Duy의 답변과 비슷하지만 나에게는 효과가 없었습니다. 또한 사용자가 편집 텍스트를 탭하고 나중에 커서 위치를 선택할 수있는 경우에만 커서를 끝으로 이동해야했습니다. 이것은 나를 위해 일한 유일한 코드입니다.

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

이것은 트릭을 안전하게 수행합니다 .

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


2

위의 답변은 저에게 효과적이지 않았습니다. 그래서 나는 새로운 해결책을 찾았습니다. 이것은 누군가에게 도움이 될 수 있습니다. 현재 날짜에 따라 최신 버전의 Android Studio, 즉 3.5를 사용하고 있습니다. 아마도 위의 답변이 효과를 보이지 않은 이유 일 수 있습니다.

암호:

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

여기서 첫 번째 인수는 재생할 스패너 블 텍스트 값이고 두 번째 인수는 인덱스 값입니다. 텍스트 끝에 커서를 원하기 때문에 텍스트의 길이를 반환하는 getText (). length ()를 사용했습니다.


1
천만에요! 행복한 코딩!
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) {

    }
}

XML 파일에서이 CustomEditText를 사용하면 작동합니다. 나는 이것을 테스트했고 그것이 나를 위해 일하고있다.


1

EditText보기에서 텍스트 끝에 커서를 놓으려면

 EditText rename;
 String title = "title_goes_here";
 int counts = (int) title.length();
 rename.setSelection(counts);
 rename.setText(title);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.