Android:如何强制使EditText失去焦点?

431

我希望能够取消EditText的焦点。比如说,如果键盘弹出并且用户通过返回按钮隐藏它,我希望焦点和光标都消失。如何实现这个功能?


在 EditText 之后,还有其他可以聚焦的视图吗? - Heidar
能否将 WebView 聚焦? - Alex1987
请查看我的回答:https://dev59.com/cm865IYBdhLWcg3wSMkw#12530226 - Sveinung Kval Bakken
5
查看此内容... https://dev59.com/iHI_5IYBdhLWcg3wBub4 - Amritpal Singh
一行代码 https://stackoverflow.com/a/46580242/6611895 - pruthwiraj.kadam
隐藏编辑框光标:editText.setCursorVisible(false); - Jayakrishnan
18个回答

445

你可以通过以下方法使光标和焦点消失:

edittext.clearFocus();

但是检测键盘隐藏是一项艰难的工作。


66
clearFocus() 不起作用。 - JaydeepW
210
它能够正常工作,但会将焦点重新设置回活动中的第一个可聚焦视图,因此如果活动中只有一个视图,您可能会认为它不起作用,但它确实可以正常工作,您需要理解它的行为 :) - Ashraf Bashir
我该如何将焦点返回到EditText?我尝试使用.requestFocus();但似乎不起作用。提前致谢。 - edwoollard
我有几个应用程序,在其中使用片段时,clearFocus()有效,在只有一个活动的应用程序中它不起作用,焦点只会跳到第一个editText。 - Leon
127
如果其他人也在努力让这个工作,如果你在你的活动或片段的根“Layout”中添加android:focusable="true"android:focusableInTouchMode="true",这将把焦点从“EditText”更改为“Layout”。 - Loyalar
这个可以工作。但是我还必须手动隐藏键盘。 - Miguel Tomás

283

您可以将此代码添加到 onCreate 中,这样每次Activity启动时就会隐藏键盘。

您还可以以编程方式将焦点更改为另一个项。

 this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

你在DialogFragment上怎样做到这一点? - Mr.Noob
@Mr.Noob 如果你的DialogFragment里有一个文本字段,那么完全一样。 - Max
3
对于像我这样一开始跳过问题下面的评论的人:@AmritpalSingh有一种更优雅的方法(只使用XML属性)来实现这一点。去看看吧! - pr-shadoko
1
要重新获得焦点,请使用 this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);editText.requestFocus(); - Prabs
注意,这需要一个窗口容器,在自定义视图内无法工作。 - desgraci
显示剩余2条评论

190

在你的XML中,在EditText之前添加LinearLayout

<LinearLayout 
    android:focusable="true"
    android:focusableInTouchMode="true" 
    android:clickable="true"
    android:layout_width="0px"
    android:layout_height="0px" />

或者您可以通过在“EditText”之前将以下行添加到视图中来执行相同的操作。

<Button
    android:id="@+id/btnSearch"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:gravity="center"
    android:text="Quick Search"
    android:textColor="#fff"
    android:textSize="13sp"
    android:textStyle="bold" />

<EditText
    android:id="@+id/edtSearch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:layout_marginRight="5dp"
    android:gravity="left"
    android:hint="Name"
    android:maxLines="1"
    android:singleLine="true"
    android:textColorHint="@color/blue"
    android:textSize="13sp"
    android:textStyle="bold" />

16
我喜欢这种解决方案,它和在我的EditText上使用.clearFocus()组合使用(该EditText是布局中第一个可聚焦的项目,因此单独使用clearFocus()不起作用)。将LinearLayout欺骗成可聚焦的是一个简单易行的解决方案。辛格·阿尔吉恩做得很好 :) - BasicPleasureModel
1
你只需要使用 android:focusableInTouchMode="true",因为将其设置为 true 也会确保该视图可聚焦。 - GuilhE
太棒了,谢谢 Singh。 - Brian
不错的解决方案。 - Varundroid
最佳且最简单的解决方案 - William
显示剩余2条评论

110

去除焦点但仍保持可聚焦性:

editText.setFocusableInTouchMode(false);
editText.setFocusable(false);
editText.setFocusableInTouchMode(true);
editText.setFocusable(true);

EditText将失去焦点,但可以在新的触摸事件上再次获得焦点。


11
这似乎是将焦点转移到下一个可聚焦的视图,而不是将焦点从编辑文本中移除。似乎Android永远不想"失去焦点"。出于这个原因,我在我的项目中选择使根布局具有焦点/focusableInTouchMode。这也有语义上的意义:当你不想聚焦在特定的编辑文本上时,将焦点设置到根布局就像是向后退一步,将注意力集中在整个活动/片段上,而不是特定的视图。 - Shane Creighton-Young
1
谢谢你的简单技巧!!!完美地解决了问题。 - shift66
1
只有这个对我有效。 - Vinh Nguyen
1
对我有用,谢谢。 - AKSHAY MANAGOOLI
2
你可以尝试使用“clearFocus”。 - Seth
如果您在EditText的onFocusChangeListener内执行此操作,在Android 6.0(Marshmallow)上会导致堆栈溢出(崩溃)。 - straya

79

将这两个属性添加到您的父布局中(例如:线性布局、相对布局)

android:focusable="true"
android:focusableInTouchMode="true" 

它能解决问题 :)


11
最佳解决方案,无需添加新视图即可运行。谢谢。 - tintin21
2
这背后的逻辑是什么? - Utsav Gupta
4
不要惊讶。安卓有时会创造出其自己的创作者不理解的奇迹。 - JaydeepW
2
应该在顶部。 - jzeferino
3
当焦点从一个视图中移开时,Android会将焦点设置在支持焦点的“第一个”视图上,这种行为具有潜在的(且无法预测的)逻辑。 - Martin Marconcini
显示剩余3条评论

78

移除 Android 中的自动聚焦 EditText

这对我有效。

编辑 在链接中他们建议使用 LinearLayout,但是简单的 View 也可以工作。

<View
    android:id="@+id/focus_thief"
    android:layout_width="1dp"
    android:layout_height="1dp"
    android:focusable="true"
    android:focusableInTouchMode="true" />

如果将这个"theif"放在布局的顶部(成为第一个可聚焦的项目),则调用clearFocus()函数将起作用。


11
虽然这个回答理论上可能会解答问题,但最好在此处包含答案的基本部分,并提供链接作为参考。 - Bill the Lizard
1
如果您的布局中有任何其他视图将使用android:focusable="true"和android:focusableInTouchMode="true"参数,则不需要添加单独的“focus_thief”视图。只需将这些参数添加到上面的视图(如果有)即可。 - Bamerza

33

在活动开始时隐藏键盘,请在onCreate()中编写以下代码。

InputMethodManager imm = (InputMethodManager)
getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);

清除焦点并从编辑框中移除光标......

editText.clearFocus();

editText.setCursorVisible(false);

2
注意:为了使editText.clearFocus();正常工作,您需要在根布局中添加android:focusableInTouchMode="true" android:focusable="true" - DIRTY DAVE

33

你也可以在清单文件的操作部分中包含android:windowSoftInputMode="stateAlwaysHidden"

这相当于:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

但是以XML的方式。

顺便提一下,你也可以使用代码隐藏键盘:

// hide virtual keyboard
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mYourEditText.getWindowToken(), 0);

我只使用了键盘的一部分,谢谢。 - magorich
1
当你不可避免地想要隐藏它时,你必须执行以下操作:https://dev59.com/j2Yq5IYBdhLWcg3woCC7#14327901 - Allison

29

尝试在您的视图中使用此代码,它对我起作用:

<View
    android:id="@+id/fucused"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:focusableInTouchMode="true"/>

5
Android的焦点管理太糟糕了,我试过各种可能的解决方案,直到感到沮丧,这条评论是唯一完美运行的选择...只需在xml中添加一个简单的视图即可解决问题(显然,当你想从其他视图中移除时,你要将焦点设置到该视图)。谢谢。 - Pedro Varela
4
"专注",没错! :D - Ahmet Noyan Kızıltan
6
我更倾向于说“我操”,但是...是的。 - Martin Marconcini
除了这个,其他的解决方案都对我没用。我的SearchView在一个片段中,并且是视图组顶部的第一个视图,因此无论我尝试什么,它都会获得焦点。 - Ishaan

24

将以下代码添加到您的父布局中,确保您已经将 EditText 放置在正确位置,并添加 android:focusableInTouchMode="true" 属性:


3
这个技巧对我很有用。如果视图是第一个“EditText”,似乎clearFocus()清除了它的焦点,但然后开始在视图树中搜索焦点候选者,最终发现相同的视图。结果是一样的。但如果你添加android:focusableInTouchMode,焦点遍历会停留在其父视图上。 - WindRider
这对我有用,谢谢。 - Mohamed Nageh
如此简单,如此有效。谢谢。 - driftwood

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