题 阻止EditText在Activity启动时获得关注


我有一个 Activity 在Android中,有两个元素:

  1. EditText 
  2. ListView

当我的 Activity 开始吧 EditText 立即有输入焦点(闪烁光标)。我不希望任何控件在启动时具有输入焦点。我试过了:

EditText.setSelected(false);

没有运气。我怎么能说服 EditText 什么时候不选择自己 Activity 开始?


2390
2017-10-12 15:03


起源


在您使用下面任何一个被投票的黑客之前,请检查您是否没有 <requestFocus /> XML布局中的行(更多详细信息,请参阅 @ floydaddict的回答)。 Eclipse的WYSIWYG编辑器会自动添加它。删除此行后,问题就消失了。 - DzinX
正好删除 <requestFocus /> 使用KitKat 4.4.4无法使用华硕Nexus 7,但@ Joe的答案有效 - user13267
我只是在我的父布局上使用android:focusableInTouchMode =“true”并且适合我。 - Herman
唯一适合我的是rallat的解决方案 - vivoconunxino
@Herman谢谢!!你的简单解决方案对我有用 - Adiyat Mubarak


答案:


Luc和Mark的优秀答案却缺少一个好的代码示例。添加标签 android:focusableInTouchMode="true" 至 <LinearLayout> 像下面的例子将解决问题。

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    android:focusable="true" 
    android:focusableInTouchMode="true"
    android:layout_width="0px" 
    android:layout_height="0px"/>

<!-- :nextFocusUp and :nextFocusLeft have been set to the id of this component
to prevent the dummy from receiving focus again -->
<AutoCompleteTextView android:id="@+id/autotext"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:nextFocusUp="@id/autotext" 
    android:nextFocusLeft="@id/autotext"/>

2032
2017-11-02 15:49



怎么样设置 亲 布局到 android:focusableInTouchMode="true"! - Muhammad Babar
完善!谢谢......有一点需要注意的是,虚拟物品必须在可聚焦元素之前放置!我的虚拟和EditText之间有一个TextView,方法不起作用! - maddob
将android:focusableInTouchMode =“true”设置为父布局是感谢@Muhammad Babar的好方法 - sujith s
谁能解释为什么这样有效? - Pietro Rea
@PietroRea Android具有恼人的自动对焦行为,这些行为内置于其应用结构的核心行为中。如果您告诉它编辑文本正在释放或失去焦点,它会自动决定焦点的位置。如果没有焦点转移到的新对象,它会在布局中选择第一个可聚焦元素,即使该元素刚刚清除了它的焦点!这有点疯狂和令人沮丧,但也许有这种行为的正当理由。 - Weston Wedding


实际问题是你根本不希望它有焦点吗?或者你不希望它通过聚焦显示虚拟键盘 EditText?我真的没有看到问题 EditText 专注于开始,但当用户没有明确要求关注时,打开softInput窗口肯定是个问题。 EditText (并打开键盘)。

如果是虚拟键盘的问题,请参阅 AndroidManifest.xml  <activity>元素 文档。

android:windowSoftInputMode="stateHidden"  - 进入活动时始终隐藏它。

要么 android:windowSoftInputMode="stateUnchanged"  - 不要改变它(例如不要改变它) 显示 如果它尚未显示,但如果在进入活动时打开,则将其保持打开状态)。


1567
2018-04-09 21:22



但是光标仍然在布局的第一个EditText中 - 即使没有显示键盘 - martyglaubitz
@Anderson:没有任何关于答案暗示它会阻止 EditText 从获得焦点。它实际上清楚地表明这是你如何阻止 软件键盘IME 从焦点上自动打开;因为更大的担忧是软键盘出乎意料地出现, 不 焦点本身。如果您的问题与 EditText 实际上有焦点,然后使用别人的答案。 - Joe
以编程方式设置它: stackoverflow.com/questions/6138330/... - Nick Franceschina
不要在带摄像头的活动上这样做 - 它会破坏闪光的时间(不要问我为什么) - Daniel Wilson
在启动时没有关注的一个原因是如果改变了imeOptions 后 视图具有焦点,键盘显示,imeOptions将是更改前设置的那些。 - n_b


存在更简单的解决方案。在父布局中设置这些属性:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true" >

现在,当活动开始时,此主要布局将默认获得焦点。

此外,我们可以通过再次将焦点放在主布局上,在运行时从子视图中删除焦点(例如,在完成子编辑之后),如下所示:

findViewById(R.id.mainLayout).requestFocus();

好评 从 Guillaume Perrot

android:descendantFocusability="beforeDescendants" 似乎是   默认值(整数值为0)。它只是通过添加工作    android:focusableInTouchMode="true"

真的,我们可以看到了 beforeDescendants 设置为默认值 ViewGroup.initViewGroup() 方法(Android 2.2.2)。但不等于0。 ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

感谢纪尧姆。


1014
2017-12-26 23:35



将这些属性设置为 直接 视图的父级关注于活动创建,否则它将无法工作。 - tomrozb
请注意,如果父级是ScrollView,这似乎不起作用 - Daniel Wilson
只是一个完美的解决方适用于两者:1。禁用自动对焦,以及2.禁用自动打开软键盘 - Meet
尼斯。它不需要是直接的父母。我将它设置在布局的根级别,似乎工作正常。 - Kurotsuki
@DanielWilson什么时候想要一个scrollview作为edittext的直接父级? - Mark Buikema


我发现的唯一解决方案是:

  • 创建一个 的LinearLayout (我不知道其他类型的布局是否有效)
  • 设置属性 android:focusable="true" 和 android:focusableInTouchMode="true"

而且 EditText 在开始活动后不会得到焦点


386
2017-10-23 08:12



简单!!我最初将这些属性添加到父视图,失败了,然后我将它们设置为另一个布局并且工作正常。谢谢!! - Rino
它也适用于RelativeLayout。 - Brian Reinhold


问题似乎来自于我只能在中看到的财产 XML form 的布局。

确保在声明的末尾删除此行 EditText XML标签:

<requestFocus />

这应该是这样的:

<EditText
   android:id="@+id/emailField"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:inputType="textEmailAddress">

   //<requestFocus /> /* <-- without this line */
</EditText>

67
2018-03-13 09:57





使用其他海报提供的信息,我使用了以下解决方案:

在布局XML中

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    android:id="@+id/linearLayout_focus"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:layout_width="0px"
    android:layout_height="0px"/>

<!-- AUTOCOMPLETE -->
<AutoCompleteTextView
    android:id="@+id/autocomplete"
    android:layout_width="200dip"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dip"
    android:inputType="textNoSuggestions|textVisiblePassword"/>

在onCreate()

private AutoCompleteTextView mAutoCompleteTextView;
private LinearLayout mLinearLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mylayout);

    //get references to UI components
    mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
    mLinearLayout = (LinearLayout) findViewById(R.id.linearLayout_focus);
}

最后,在onResume()

@Override
protected void onResume() {
    super.onResume();

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}

63
2018-05-26 21:07





以下内容将阻止edittext在创建时获得焦点,但在触摸时抓住它。

<EditText
    android:id="@+id/et_bonus_custom"
    android:focusable="false" />

所以你在xml中将focusable设置为false,但关键是在java中,你添加了以下监听器:

etBonus.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.setFocusable(true);
        v.setFocusableInTouchMode(true);
        return false;
    }
});

因为您返回假,即不消耗该事件,所以聚焦行为将正常进行。


58
2018-06-15 04:45



但是这将永远不会成为焦点,如何只关注初始(活动开始)? - Jayesh
在其他触摸操作之前调用onTouchListener。因此,通过在触摸时实现可聚焦,标准焦点在第一次触摸时发生。键盘会出现一切。 - MinceMan
我认为这是最好的方法。此外,上面的mumbo-jumbo xml魔术虚拟代码不适用于一组复杂的编辑文本......如果这样做,我将明确地投票。 - Radu
但是如果您有多个编辑文本,它将专注于下一个编辑文本并打开键盘,因此最好添加 机器人:windowSoftInputMode = “stateAlwaysHidden” 在特定活动的清单中。 - Karan sharma
注意:在Android P上,系统将不再获取默认焦点。这意味着从P.开始这个hack是不必要的。 - MinceMan


尝试 clearFocus() 代替 setSelected(false)。 Android中的每个视图都具有可聚焦性和可选择性,我认为您只想清除焦点。


54
2017-10-12 19:02



这听起来很有希望,但是应该在Activity生命周期的哪个阶段调用它?如果我在onCreate()中调用它,EditText仍然具有焦点。它应该在onResume()或其他位置调用吗?谢谢! - Mark
我把接受的答案和这个答案结合起来。我打了电话 myEditText.clearFocus(); myDummyLinearLayout.requestFocus(); 在里面 onResume 活动。这确保了EditText在手机旋转时无法保持焦点。 - teedyay


我曾单独尝试过serval回答,但重点仍然是EditText。我只能通过一起使用上述两个解决方案来解决它。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/mainLayout"
  android:descendantFocusability="beforeDescendants"
  android:focusableInTouchMode="true" >

(参考Silver https://stackoverflow.com/a/8639921/15695 )

并删除

 <requestFocus />

在EditText

(参考floydaddict https://stackoverflow.com/a/9681809 )


43
2017-11-28 10:32



我不得不添加edittext.clearFocus()以及上面的工作:) - Nav


这些解决方案都不适合我。我修复自动对焦的方式是:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>

37
2017-11-30 16:37



android:windowSoftInputMode =“adjustPan”对Android Manifest中的任何活动 - rallat
不知道你是怎么想出来的,但不仅如此!这很有效。 - portfoliobuilder


简单解决方案 在 AndroidManifest 在 Activity 标签使用

android:windowSoftInputMode="stateAlwaysHidden"

31
2018-03-17 15:42



严格来说,这并不能解决问题。 OP表示:“我不希望任何控制在启动时具有输入焦点。”您的解决方案只隐藏键盘,这是一个不同的区别。 - katzenhut
最佳方案!!已知上述解决方案对我有用。在这件小事上浪费了大约一个小时 - Hamza Zaidi
@katzenhut是的,这就是我对这个答案的问题。专注于我的edittext会打开PlaceAutoComplete活动,因此这个答案是不完整的 - Zach
如果问题是:我如何始终确保我的活动从不显示键盘,那么这个答案就完整了。哪个不是。 - Martin Marconcini