【发布时间】:2012-06-25 14:11:34
【问题描述】:
我正在寻找一种方法来防止用户将光标位置移动到任何地方。光标应始终停留在当前 EditText 值的末尾。除此之外,用户应该不能在 EditText 中选择任何内容。您知道如何在 Android 中使用 EditText 实现这一点吗?
澄清一下:用户应该能够插入文本,但只能在末尾。
【问题讨论】:
标签: android android-edittext textselection android-cursor
我正在寻找一种方法来防止用户将光标位置移动到任何地方。光标应始终停留在当前 EditText 值的末尾。除此之外,用户应该不能在 EditText 中选择任何内容。您知道如何在 Android 中使用 EditText 实现这一点吗?
澄清一下:用户应该能够插入文本,但只能在末尾。
【问题讨论】:
标签: android android-edittext textselection android-cursor
是的,我知道怎么做 =) 就去做吧:
复制辅助类:
class SelectionSpanWatcher(
private val listener: OnChangeSelectionListener
) : SpanWatcher {
override fun onSpanAdded(text: Spannable?, what: Any?, start: Int, end: Int) {
/* do nothing */
}
override fun onSpanRemoved(text: Spannable?, what: Any?, start: Int, end: Int) {
/* do nothing */
}
override fun onSpanChanged(text: Spannable?, what: Any?, oStart: Int, oEnd: Int, nStart: Int, nEnd: Int) {
when (what) {
SELECTION_START -> listener.onSelectionChanged(Selection.START, oStart, oEnd, nStart, nEnd)
SELECTION_END -> listener.onSelectionChanged(Selection.END, oStart, oEnd, nStart, nEnd)
}
}
enum class Selection {
START,
END
}
fun interface OnChangeSelectionListener {
fun onSelectionChanged(selection: Selection, oStart: Int, oEnd: Int, nStart: Int, nEnd: Int)
}
}
然后复制扩展方法:
fun Editable.setOnSelectionChangedListener(listener: OnChangeSelectionListener?) {
getSpans(0, length, SelectionSpanWatcher::class.java)
.forEach { span -> removeSpan(span) }
if (listener != null) {
setSpan(SelectionSpanWatcher(listener), 0, length, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
}
}
然后使用复制的代码如下(使用androidx.core.widget.addTextChangedListener from android-ktx):
editText.addTextChangedListener(afterTextChanged = { editable ->
editable?.setOnSelectionChangedListener { _, _, _, _, _ ->
editText.postOnAnimation {
editText.setSelection(editText.text.length)
}
}
})
【讨论】:
试试这个:
mEditText.setMovementMethod(null);
【讨论】:
mEditText.setMovementMethod(null);,我仍然可以移动光标
我遇到了同样的问题。这最终对我有用:
public class CustomEditText extends EditText {
@Override
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);
}
}
【讨论】:
return 以便我们每次都明确地调用super 吗?为什么?当有人根据自己的需要调整此代码时,很容易产生错误:我的用户可能会选择除前两个之外的所有字母。选择多个字母然后移动选择的右侧会破坏您的解决方案,但适用于我的解决方案:)
听起来最好的方法是创建自己的CustomEditText 类并覆盖/修改任何相关方法。您可以在此处查看 source code 对应的 EditText。
public class CustomEditText extends EditText {
@Override
public void selectAll() {
// Do nothing
}
/* override other methods, etc. */
}
【讨论】:
这会将光标焦点重置到文本的最后一个位置
editText.setSelection(editText.getText().length());
此方法将禁用触摸时光标移动
public class MyEditText extends EditText{
@Override
public boolean onTouchEvent(MotionEvent event)
{
final int eventX = event.getX();
final int eventY = event.getY();
if( (eventX,eventY) is in the middle of your editText)
{
return false;
}
return true;
}
}
你可以使用xml属性中的任何一个
android:cursorVisible
或者java函数
setCursorVisible(boolean)
禁用edittext的闪烁光标
【讨论】:
onKeyDown() 恶作剧所处理。而且,这不会禁用选择,我不知道这是否可能。