【问题标题】:How to disable cursor positioning and text selection in an EditText? (Android)如何在 EditText 中禁用光标定位和文本选择? (安卓)
【发布时间】:2012-06-25 14:11:34
【问题描述】:

我正在寻找一种方法来防止用户将光标位置移动到任何地方。光标应始终停留在当前 EditText 值的末尾。除此之外,用户应该不能在 EditText 中选择任何内容。您知道如何在 Android 中使用 EditText 实现这一点吗?

澄清一下:用户应该能够插入文本,但只能在末尾。

【问题讨论】:

    标签: android android-edittext textselection android-cursor


    【解决方案1】:

    是的,我知道怎么做 =) 就去做吧:

    复制辅助类:

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

    【讨论】:

      【解决方案2】:

      试试这个:

      mEditText.setMovementMethod(null);
      

      【讨论】:

      • 即使使用mEditText.setMovementMethod(null);,我仍然可以移动光标
      • 是的,使用触摸指针,但不再使用键盘箭头键,d-pad。
      【解决方案3】:

      我遇到了同样的问题。这最终对我有用:

      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 吗?为什么?当有人根据自己的需要调整此代码时,很容易产生错误:我的用户可能会选择除前两个之外的所有字母。选择多个字母然后移动选择的右侧会破坏您的解决方案,但适用于我的解决方案:)
      【解决方案4】:

      听起来最好的方法是创建自己的CustomEditText 类并覆盖/修改任何相关方法。您可以在此处查看 source code 对应的 EditText

      public class CustomEditText extends EditText {
      
          @Override
          public void selectAll() {
              // Do nothing
          }
      
          /* override other methods, etc. */
      
      }
      

      【讨论】:

        【解决方案5】:

        这会将光标焦点重置到文本的最后一个位置

        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的闪烁光标

        【讨论】:

        • 请注意,您仍然需要担心箭头键/轨迹球/D-pad 会改变光标位置——这可能会被某种onKeyDown() 恶作剧所处理。而且,这不会禁用选择,我不知道这是否可能。
        • 谢谢,但这不是我正在寻找的解决方案。禁用视图上的所有触摸事件的问题在于,您根本无法聚焦视图。而且我想要一个闪烁的光标 - 应该禁用移动光标的可能性。
        猜你喜欢
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 2011-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多