编辑框关闭软键盘后光标仍在闪烁

12
在关闭软键盘后,Edittext光标是否应该继续闪烁?还是这只是在模拟器上测试时发生的结果,在实际设备上不会发生?--正如此讨论中第二篇帖子所指出的。
更新:
我知道Edittext仍然有光标闪烁,因为它们仍然处于焦点状态--当edittext失去焦点时记录了一条消息,但在关闭软键盘时未记录该消息。
更新:
我已尝试执行:
@Override
public void onBackPressed() {
    super.onBackPressed();
    getCurrentFocus().clearFocus();
}
因此,每次关闭键盘时,当前焦点的EditText将失去焦点,并调用onFocusChanged()。问题在于,当键盘弹起时按下返回按钮时,onBackPressed()不会被调用。我知道这是因为我在onBackPressed()中放置了一个toast,但是当键盘弹起时按下返回按钮时,没有toast显示出来。

这是因为在关闭软键盘时,您上次编辑的文本从未失去焦点。 您可以向编辑文本添加setOnKeyListener,并在按下“完成”按钮(Enter)或“返回”按钮时将焦点更改为另一个布局组件。 - JJ86
@JJ86 我无法使用 setOnKeyListener,因为有可选的 EditTexts,所以不可能知道用户在按下“完成”按钮时是想填写下一个可选的 EditText 还是已经全部完成。我尝试重写 onBackPressed,但遇到了这个问题,还没有找到解决方案。 - the beest
我明白了,但是如果将其与setOnFocusChangeListener结合起来,检测哪一个获得了焦点呢? - JJ86
@JJ86,除非是最后一个,否则焦点在哪里并不重要,因为只有一个操作需要进行——提交表单。至于其他的,没有确定的方法来判断用户点击Enter键时是否想要进入下一个EditText或提交表单,这与EditText是否具有焦点无关。 - the beest
7个回答

1

首先创建一个自定义的EditText。以下是一个示例,当按下键盘返回按钮时,具有回调以关闭键盘。

public class EdittextListner extends EditText {

private KeyImeChange keyImeChangeListener;

public EdittextListner(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public void setKeyImeChangeListener(KeyImeChange listener) {
    keyImeChangeListener = listener;
}

public interface KeyImeChange {
    public boolean onKeyIme(int keyCode, KeyEvent event);
}

@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
    if (keyImeChangeListener != null) {
        return keyImeChangeListener.onKeyIme(keyCode, event);
    }
    return false;
}

}

其次,将您的EditText更改为EdittextListner在您的布局文件中。 最后执行以下操作。
 mLastNameEditText.setKeyImeChangeListener(new EdittextListner.KeyImeChange() {
        @Override
        public boolean onKeyIme(int keyCode, KeyEvent event) {
            mLastNameEditText.clearFocus();
            return true;
        }
    });

这对我有用。希望能帮到你。


这段代码如何区分后退按钮被按下和其他按键? - the beest
这对我不起作用。它能检测到软键盘的返回按钮、硬件键盘的返回按钮还是手机的硬件返回按钮吗? - the beest
在重写的 onKeyPreIme() 方法中,你可以像下面这样检查后退键是否被按下: if (event.getAction()==KeyEvent.ACTION_UP && keyCode==KeyEvent.KEYCODE_BACK)这段代码可以检测到硬件后退键的按下。 - Avinash4551

1
编辑文本是一种视图,可以接受用户的输入,因此它与键盘打开或关闭无关。当用户单击编辑文本时,该编辑文本将获得焦点,并开始闪烁光标以进行输入。
因此,您可以在关闭键盘的同时设置该编辑文本的光标可见性,这样它就不会继续闪烁。
为此,您需要在隐藏键盘时编写以下行。
    editTextObject.setCursorVisible(false);

这将停止光标闪烁。

问题在于我没有隐藏键盘,是用户通过按返回按钮来隐藏的。 - the beest
你可以实现该时间键盘隐藏函数,然后在其中设置光标可见性如上所述,因此当用户单击返回按钮并且键盘被隐藏时,它将调用此函数并从EditText中隐藏光标。 - Vickyexpert

0

正如你所说,EditText 中闪烁的光标与 EditText 获得焦点有关,但显示或隐藏软键盘与 View 获得或失去焦点无关。任何 View(包括 EditText)都可以独立于软键盘是否显示而获得焦点,EditText 本身没有任何内在特性会使其表现不同。

如果你想让 EditText 在软键盘隐藏时失去焦点,你需要通过监听软键盘可见性的变化并相应地更新 EditText 来实现这个功能。


是的,但我还没有看到有人在活动的 windowSoftInputMode="adjustPan" 时破解软键盘监听器的示例。 - the beest
我明白了...我可以问一下为什么在隐藏键盘后继续使用该活动很重要吗?例如,在填写表格或启动搜索时,用户不需要强制隐藏键盘任何时间,并且如果他们这样做,他们可能希望保留光标,以便他们可以轻松找到上次输入信息的位置,以便继续之前的工作。 - happydude
好的,为了让用户提交表单,他们必须点击屏幕底部的按钮,因此用户必须关闭键盘才能到达它--当键盘弹出时,无法滚动到该按钮...我是否没有办法在软键盘隐藏时清除视图上的焦点? - the beest
我不确定,但我保证在填写EditText后通过键盘提交表单会更容易。在布局中保留按钮,但查看TextView的IME选项,特别是setImeActionLabel()和setImeOptions()。布局中也有相应的xml属性可供使用。这些选项允许您从软键盘直接“点击”现有的表单提交按钮。 - happydude
这并不简单。布局底部附近的EditText描述是可选的,因此当用户在完成描述前面的EditText时按下回车键时,无法确定是否提交表单或转到描述EditText。 - the beest

0
唯一知道键盘是否消失的方式是覆盖OnglobalLayout并检查高度。 基于该事件,您可以在您的编辑文本上“setCursorVisible(false)”。

如果活动在清单中具有属性android:windowSoftInputMode="adjustPan",则此方法无效。 - the beest

0

更多信息,请查看此链接

RelativeLayout mainLayout = findViewById(R.layout.main_layout); // You must use the layout root
InputMethodManager im = (InputMethodManager)  getSystemService(Service.INPUT_METHOD_SERVICE);

/*
Instantiate and pass a callback
*/
SoftKeyboard softKeyboard;
softKeyboard = new SoftKeyboard(mainLayout, im);
softKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged()
{

@Override
public void onSoftKeyboardHide() 
{
    // Code here
  EditText.clearFocus();
}

@Override
public void onSoftKeyboardShow() 
{
    // Code here
}   
});

/*
Open or close the soft keyboard easily
*/
softKeyboard.openSoftKeyboard();
softKeyboard.closeSoftKeyboard();

/* Prevent memory leaks:
*/
@Override
public void onDestroy()
{
super.onDestroy();
softKeyboard.unRegisterSoftKeyboardCallback();
}

0

试试这个:

public class EditTextBackEvent extends EditText {

private EditTextImeBackListener mOnImeBack;

public EditTextBackEvent(Context context) {
    super(context);
}

public EditTextBackEvent(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public EditTextBackEvent(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
        if (mOnImeBack != null) mOnImeBack.onImeBack(this, this.getText().toString());
    }
    return super.dispatchKeyEvent(event);
}

public void setOnEditTextImeBackListener(EditTextImeBackListener listener) {
    mOnImeBack = listener;
}

public interface EditTextImeBackListener {
    void onImeBack(EditTextBackEvent ctrl, String text);
}
  }

在你的布局中:

<yourpackagename.EditTextBackEvent
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                />

并且在你的片段中:

edittext.setOnEditTextImeBackListener(new EditTextBackEvent.EditTextImeBackListener()
    {
        @Override
        public void onImeBack(EditTextBackEvent ctrl, String text)
        {
           edittext.clearfocus();
        }
    });

-1

尝试在布局中保留一个可聚焦的视图,该视图位于您的editText上方。

<View
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:focusable="true"
    android:focusableInTouchMode="true" />

这应该可以工作,因为空白的可聚焦视图应该会捕获焦点,而不是您的EditText。


如果你读了问题,你就会知道问题在于 clearFocus 没有被调用,而不是它被调用但没有起作用。 - the beest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接