我正在更改keyListener上的EditText的值。

但是当我更改文本时,光标移动到EditText的开头。 我需要光标在文本的末尾。

如何将光标移动到EditText文本的末尾。


您应该能够在EditText的方法setSelection()的帮助下实现这一点,请参阅这里


试试这个:

更新:

科特林:

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

Java:

editText.setSelection(editText.getText().length());

有一个名为append for ediitext的函数,它将字符串值追加到当前edittext值,并将光标放在值的末尾。 你可以将字符串值本身作为当前编辑文本值,并调用append();

myedittext.append("current_this_edittext_string"); 

我认为这可以达到你想要的效果。

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

你也可以像这样把光标放在EditText视图中文本的末尾:

EditText et = (EditText)findViewById(R.id.textview);
int textLength = et.getText().length();
et.setSelection(textLength, textLength);

如果你之前调用setText并且新的文本没有得到布局阶段调用setSelection在一个单独的runnable中由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()。


这是另一种可能的解决方案:

et.append("");

如果因为某种原因不管用,试试下面的方法:

et.setSelection(et.getText().length());

editText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        editText.setSelection(editText.getText().length());
        return false;
    }
});

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

这对我很有用!


类似于@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;
    }
});

这个方法很安全:

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

如果你的EditText不清楚:

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

or

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

如果你想选择所有文本,只是输入新的文本而不是旧的,你可以使用

    android:selectAllOnFocus="true"

我测试过的所有其他代码都没有很好地工作,因为用户仍然可以将插入符号/光标放在字符串中间的任何地方(例如: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) {

    }
});

希望能有所帮助!


这是

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

科特林:

将光标设置到起始位置:

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)

下面的Code是将光标放在第二个字符之后:

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

JAVA:

将光标设置到起始位置:

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

下面的Code是将光标放在第二个字符之后:

EditText editText = (EditText)findViewById(R.id.edittext_id);
editText.setSelection(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) {

    }
}

在XML文件中使用此CustomEditText,这将起作用。我已经测试过了,它对我很有效。


editText。这里的setSelection很神奇。基本上选择让你把光标放在任何你想要的位置。

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

这将光标放置到EditText的末尾。基本上,editText.getText().length()会给出文本长度。然后使用setSelection with length。

editText.setSelection(0);

它用于将光标设置在起始位置(0)。


试试这个:

<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()); // Set cursor end point


这个问题已经很老了,但我认为如果你想使用Android上最新发布的DataBinding工具,有这个答案可能会很有用,只需在XML中设置这个:

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

在我的情况下,我创建了以下Kotlin ext.函数,可能对某人有用:

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

然后按如下方式使用:

mEditText.focus()

如果您想将光标放置在EditText视图中文本的末尾

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

etSSID.setSelection(etSSID.getText().length());

用于ViewModel, LiveData和Data绑定

我需要这个功能的EditText与多行支持在我的笔记应用程序。我想在文本结尾的光标,当用户导航到有笔记文本的片段。

djleop建议的解决方案很接近。但这样做的问题是,如果用户将光标放在文本中间进行编辑并开始输入,光标将再次跳转到文本的末尾。这是因为LiveData会发出新的值,光标会再次跳转到文本的末尾,导致用户无法编辑中间的文本。

为了解决这个问题,我使用MediatorLiveData,并使用标志仅为其分配一次String长度。这将导致LiveData只读取值一次,即当用户导航到片段时。在此之后,用户可以将光标放在任何他们想要编辑文本的地方。

ViewModel

private var accessedPosition: Boolean = false

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

在这里,youobjecject是从数据库检索到的另一个LiveData,该数据库包含您在EditText中显示的String文本。

然后使用绑定适配器将此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类类似于由Jose Alcérreca从谷歌编写的SingleLiveEvent。我在这里使用它来处理屏幕旋转。使用单个事件将确保当用户编辑文本在中间的某个地方并且屏幕旋转时,光标不会跳到文本的末尾。当屏幕旋转时,它将保持相同的位置。

下面是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
}

这是适合我的解决方案,提供了良好的用户体验。希望它对你的项目也有帮助。


上面的答案对我没用。所以我找到了一个新的解决方案。这可能对某些人有帮助。我一直在使用最新版本的Android Studio,即目前为止的3.5。也许这就是以上答案没有显示出任何效果的原因。

代码:

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

这里,第一个参数是你想要使用的Spannable文本值,而第二个参数是索引值。因为我们希望光标位于文本的末尾,所以我们使用getText().length()来返回文本的长度


editText.accessibilityDelegate = object : View.AccessibilityDelegate() {
    override fun sendAccessibilityEvent(host: View?, eventType: Int) {
        super.sendAccessibilityEvent(host, eventType)
        if (eventType == TYPE_VIEW_TEXT_SELECTION_CHANGED) {
            editText.setSelection(editText.length())
        }
    }
}

完全工作的解决方案!!

kotlin,你需要用post

fun EditText.placeCursorToEnd() {
    this.setOnFocusChangeListener { v, hasFocus ->
        if (hasFocus) {
            v.post { this.setSelection(text.length) }
        }
    }
    this.setOnClickListener {
        it.post { this.setSelection(text.length) }
    }
}