Android 当焦点不在EditText上时,在EditText内显示光标

Android 当焦点不在EditText上时,在EditText内显示光标,android,android-edittext,Android,Android Edittext,我正在开发Android智能电视应用程序: 在视图中有一个自定义键盘和一个编辑文本 当应用程序启动时,焦点转到键盘 所需: 当用户使用键盘键入(用遥控器单击)时,光标也应在编辑文本中闪烁 如何在编辑文本中显示此效果?在布局xml文件中,在编辑文本中添加以下行: <requestFocus/> 这将把光标放在editText小部件中 希望有帮助。您可以在活动中使用以下代码: //Get the EditText using EditText et = (EditText)

我正在开发Android智能电视应用程序:

  • 视图中
    有一个自定义键盘和一个
    编辑文本

  • 当应用程序启动时,焦点转到键盘

    所需:

    • 当用户使用键盘键入(用遥控器单击)时,光标也应在
      编辑文本中闪烁

如何在
编辑文本中显示此效果?

在布局xml文件中,在编辑文本中添加以下行:

<requestFocus/>

这将把光标放在editText小部件中


希望有帮助。

您可以在活动中使用以下代码:

//Get the EditText using
EditText et = (EditText)findViewById(R.id.editText); 

//Set setCursorVisible to true
et.setCursorVisible(true);

有几种方法可以做到这一点:

1) XML

2) 爪哇


你可以做到这一点。我希望/认为你已经为你创建的按钮设置了一个布局,通过这个布局,你可以为该布局设置一个焦点侦听器,在onFocusChange方法中,你可以检查
如果(layout.hasFocus())
并执行此操作

例如,如果您的editText命名为et,您可以将其设置为:

et.setActivated(true);
et.setPressed(true);
我有一个小的示例代码,你有两个编辑文本

 et2.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {

            if(et2.hasFocus()){

                //et1.setCursorVisible(true);
                et1.setActivated(true);
                et1.setPressed(true);

            }
        }
    });
这将始终关注edittext上的第一个字符


如果为字段设置背景,则会发生这种情况。如果要解决此问题,请将
游标可绘制设置为
@null

你应该加上

对将在插入光标下绘制的可绘制图形的引用


您可以尝试以下方法:

editText.setText(text);
editText.setPressed(true);
editText.setSelection(editText.getText().length()); // moves the cursor to the end of the text
var msgEditText = dialog.findViewById(R.id.msg1textView) as EditText

msgEditText.isActivated = true
msgEditText.isPressed = true
msgEditText.requestFocus()
msgEditText.setSelection(view.getText().length)
但是,这种方法存在两个问题:

  • 光标不会闪烁。闪烁的逻辑在编辑器类中,无法重写。它要求对EditText进行对焦,并且在一个窗口中一次只能对焦一个视图-在您的情况下,这将是一个键盘按钮

    /**
     * @return True when the TextView isFocused and has a valid zero-length selection (cursor).
     */
    private boolean shouldBlink() {
        if (!isCursorVisible() || !mTextView.isFocused()) return false;
        ...
    }
    
  • 光标并不总是可见的。光标的闪烁取决于系统时间-它在半秒钟内可见,在接下来的半秒钟内隐藏。只有在根据系统时间光标可见的时间点调用我上面建议的代码时,光标才会可见
  • 这就是本机键盘/IME工作方式的原因。它是一个单独的窗口,允许EditText保持焦点并具有闪烁光标功能,同时用户在不同窗口(键盘/IME)中点击视图

    也就是说,上面的问题有一个解决方法-当您不再需要时,请确保将shouldBlink设置为false,否则会导致内存泄漏或崩溃:

    private void blink() {
        if (shouldBlink) {
            editText.setText(editText.getText());
            editText.setPressed(true);
            editText.setSelection(editText.getText().length());
    
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (shouldBlink) {
                        blink();
                    }
                }
            }, 500);
        }
    }
    

    我知道这是necro,但这比上面的解决方案要好得多。只需扩展编辑文本并添加:

      @Override
      public boolean isCursorVisible() {
        return true;
      }
    
      @Override
      public boolean isFocused() {
        return true;
      }
    
    在XML中:

      <com.foo.MyEditText
        ...
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:clickable="false"
        android:cursorVisible="true"/>
    
    
    
    现在,
    EditText
    认为它是聚焦的,光标是可见的,但实际上它不能聚焦

        private void setFocusCursor(){
      mBinding.replyConversationsFooter.footerEditText.setFocusable(true);
      `mBinding.replyConversationsFooter.footerEditText.setFocusableInTouchMode(true);`
     `mBinding.replyConversationsFooter.footerEditText.requestFocus();` 
        }
    
    只需在oncreateView()中调用此函数,就可以了。
    我们只能设置一个窗口,并且只关注一个窗口。这样做将帮助您解决问题。

    在API 27、28模拟器上测试

    删除
    background
    属性,添加
    focusable

    <EditText
        ...
        android:focusable="true"
        android:focusableInTouchMode="true"
        />
    
    它在API27、28模拟器上工作,但在真实设备(API21)上光标消失。我在这里和那里尝试了许多变体,但没有任何帮助

    然后我注意到当
    EditText
    至少包含一个符号时,它会显示游标。我添加了一个
    TextWatcher
    ,以便在未输入任何内容时添加一个空格

    private lateinit var someText: String
    
    ...
    edit.requestFocus()
    edit.setText(" ")
    edit.addTextChangedListener(YourTextWatcher())
    
    
    private inner class YourTextWatcher : TextWatcher {
    
        override fun afterTextChanged(s: Editable?) {
            someText = s.toString().trim()
            if (someText.isEmpty()) {
                // To not fall into infinite loop.
                if (s?.length != 1) {
                    edit.setText(" ")
                }
            } else {
            }
        }
    
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    }
    
    您还可以添加填充,以便在
    EditText
    内部点击,如果它很小。

    只需添加即可

    editText.requestFocus()

    我喜欢这样:

    editText.setText(text);
    editText.setPressed(true);
    editText.setSelection(editText.getText().length()); // moves the cursor to the end of the text
    
    var msgEditText = dialog.findViewById(R.id.msg1textView) as EditText
    
    msgEditText.isActivated = true
    msgEditText.isPressed = true
    msgEditText.requestFocus()
    msgEditText.setSelection(view.getText().length)
    

    请发布一些您迄今为止尝试过的代码。@Keshav1234到目前为止,我已经做了一个布局,其中包括自定义键盘和编辑文本。并手动将焦点设置在键盘上。当foucs转到编辑文本时,CURSOR可见。但我的要求是,在编辑文本时,光标应该始终闪烁。我应该改变我的方法吗?请提出建议。我想知道,Android电视上也有API吗?如果是,为什么不以这种方式实现您的自定义键盘呢?如果我这样做,那么请求将转到EditText。但根据我的要求,焦点应该放在键盘视图(GridView)上,光标应该在编辑文本时闪烁。你所说的焦点到底是什么意思?实际上我正在开发智能电视应用程序,在这个应用程序上,我们可以通过远程左、右、上、下按钮将焦点从一个视图移动到另一个视图。在我的xml中有GridView(9x9-用于键入edittext的键盘)和edittext。然后,当我点击网格时,在edittext中键入字母shuld,光标也应该闪烁。在我的情况下,它不起作用。我用xml和代码设置它,但不起作用。首先,我已经尝试用xml设置setCursorVisible,但不起作用。第二件事我的重点不是编辑文本。请参阅所附图片。重点始终放在键盘上。谢谢你的回答。通过你的代码,我可以看到光标。但光标位置是固定的。要求是,当我点击按钮时,光标应该在editetext内移动。非常感谢!这个blink()方法就是我的解决方案!这类作品。不受欢迎的UI工件,因为编辑文本的内容不断被重画,并且当您键入时,光标从文本的开头到结尾来回移动。此解决方案有效(但在我的案例中,稍后崩溃),但光标不断被重画。而且它总是尝试移动到
    EditText
    的右端。刚刚在API 27 emulator上测试过,光标是隐藏的,直到删除
    android:background=“@color/transparent”
    。奇怪的解决方案。可能有效,我不知道,但在三星Galaxy S4上,当EditText为空时,光标闪烁且不可见。退格也不起作用。
        private void setFocusCursor(){
      mBinding.replyConversationsFooter.footerEditText.setFocusable(true);
      `mBinding.replyConversationsFooter.footerEditText.setFocusableInTouchMode(true);`
     `mBinding.replyConversationsFooter.footerEditText.requestFocus();` 
        }
    
    <EditText
        ...
        android:focusable="true"
        android:focusableInTouchMode="true"
        />
    
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <size
            android:width="1dp"
            android:height="25dp"
            />
        <solid android:color="@color/gray" />
    </shape>
    
    private lateinit var someText: String
    
    ...
    edit.requestFocus()
    edit.setText(" ")
    edit.addTextChangedListener(YourTextWatcher())
    
    
    private inner class YourTextWatcher : TextWatcher {
    
        override fun afterTextChanged(s: Editable?) {
            someText = s.toString().trim()
            if (someText.isEmpty()) {
                // To not fall into infinite loop.
                if (s?.length != 1) {
                    edit.setText(" ")
                }
            } else {
            }
        }
    
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    }
    
    var msgEditText = dialog.findViewById(R.id.msg1textView) as EditText
    
    msgEditText.isActivated = true
    msgEditText.isPressed = true
    msgEditText.requestFocus()
    msgEditText.setSelection(view.getText().length)