停止EditText在Activity启动时获得焦点

Mar*_*ark 2770 android listview focus android-edittext

Activity在Android中有两个元素:

  1. EditText
  2. ListView

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

EditText.setSelected(false);
EditText.setFocusable(false);
Run Code Online (Sandbox Code Playgroud)

没运气.如何说服开始EditText时不选择自己Activity

Mor*_*son 2496

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"/>
Run Code Online (Sandbox Code Playgroud)

  • 如何将*parent*布局设置为`android:focusableInTouchMode ="true"`! (684认同)
  • 完善!谢谢......有一点需要注意的是,虚拟物品必须在可聚焦元素之前放置!我的假人和EditText之间有一个TextView,方法不起作用! (24认同)
  • 将android:focusableInTouchMode ="true"设置为父布局是感谢@Muhammad Babar的好方法 (23认同)
  • 谁能解释为什么这样有效? (22认同)
  • @PietroRea Android具有恼人的自动对焦行为,这些行为内置于其应用结构的核心行为中.如果您告诉它编辑文本正在释放或失去焦点,它会自动决定焦点的位置.如果没有焦点转移到的新对象,它会在布局中选择第一个可聚焦元素,即使该元素刚刚清除了它的焦点!这有点疯狂和令人沮丧,但也许有这种行为的正当理由. (17认同)
  • 伟大的代码,帮助了我很多:)试图改进它,`android:focusableInTouchMode ="true"`涵盖`android:focusable ="true"`+更多,所以在这种情况下`android:focusable ="true "`是不必要的,可以删除.此外,虚拟视图可以是View而不是LinearLayout.这样可以节省处理能力+从一些警告中省去你.因此,我的建议是用`<View android:focusableInTouchMode ="true"android:layout_width ="0px"android:layout_height ="0px"/>替换虚拟视图 (5认同)
  • 我只想补充一点,如果你将它应用于许多布局,不要忘记检查`<requestFocus />`并删除它,否则此修复将无法正常工作. (4认同)
  • @Muhammed Babar:我曾经设置了父布局的foucusable ="true"和android:focusableInTouchMode ="true". (2认同)
  • 使用Android P时,应考虑以下更改:“面积为0(宽度或高度为0)的视图不再可聚焦。此外,活动不再隐式分配触摸模式下的初始焦点。而是由您自己决定明确要求初始关注。” (2认同)

Joe*_*Joe 1650

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

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

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

或者android:windowSoftInputMode="stateUnchanged"-不要改变它(例如,不要显示,如果尚未出它,但如果它在进入活动时是开着的,把它打开).

  • @Anderson:答案没有暗示它会阻止`EditText`获得焦点.它实际上清楚地表明,这是你如何防止*软件键盘IME*在焦点上自动打开; 因为更大的担忧是软键盘出乎意料地出现,****不是焦点本身.如果您的问题是`EditText`实际上有焦点,那么使用别人的答案. (38认同)
  • 但是光标仍然在布局的第一个EditText中 - 即使没有显示键盘 (23认同)
  • 不要在带摄像头的活动上这样做 - 它会打破闪光的时间(不要问我为什么) (3认同)

小智 1110

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true" >
Run Code Online (Sandbox Code Playgroud)

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

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

findViewById(R.id.mainLayout).requestFocus();
Run Code Online (Sandbox Code Playgroud)

好评论纪尧姆·佩罗:

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

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

感谢Guillaume.

  • 请注意,如果父级是ScrollView,这似乎不起作用 (29认同)
  • 只是一个完美的解决方 适用于两者:1.禁用自动对焦,以及2.禁用自动打开软键盘 (4认同)

小智 418

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

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

并且EditText在开始活动后不会得到关注


flo*_*ict 80

问题似乎来自于我只能在XML form布局中看到的属性.

确保在EditTextXML标记内的声明末尾删除此行:

<requestFocus />
Run Code Online (Sandbox Code Playgroud)

这应该是这样的:

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

   //<requestFocus /> /* <-- without this line */
</EditText>
Run Code Online (Sandbox Code Playgroud)


Som*_*ere 71

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

在布局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"/>
Run Code Online (Sandbox Code Playgroud)

在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);
}
Run Code Online (Sandbox Code Playgroud)

最后,在onResume()

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

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

  • 这实际上是唯一对我有用的答案。添加 ```android:focusable="true" android:focusableInTouchMode="true"``` 可防止 EditTexts 在某些设备上获得焦点,但在某些设备上它仍然不起作用。我已经寻找解决方案很长时间了,而且效果非常好。非常感谢。 (2认同)

Eri*_*ill 69

尝试使用clearFocus()而不是setSelected(false).Android中的每个视图都具有可聚焦性和可选择性,我认为您只想清除焦点.

  • 我将接受的答案与这个答案结合起来.我打电话给`myEditText.clearFocus(); myDummyLinearLayout.requestFocus();`在Activity的`onResume`中.这确保了EditText在手机旋转时无法保持焦点. (8认同)

Min*_*Man 68

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

<EditText
    android:id="@+id/et_bonus_custom"
    android:focusable="false" />
Run Code Online (Sandbox Code Playgroud)

所以你在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;
    }
});
Run Code Online (Sandbox Code Playgroud)

因为您返回false,即不消耗该事件,所以聚焦行为将像平常一样进行.

  • 但是这将永远不会成为焦点,如何只关注初始(活动开始)? (6认同)

Lee*_*ong 59

我曾单独尝试了几个答案,但重点仍然是EditText.我只是通过使用以下两个解决方案来设法解决它.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/mainLayout"
  android:descendantFocusability="beforeDescendants"
  android:focusableInTouchMode="true" >
Run Code Online (Sandbox Code Playgroud)

(来自Silver的参考/sf/answers/604794501/)

并删除

 <requestFocus />
Run Code Online (Sandbox Code Playgroud)

在EditText

(参考文献floydaddict /sf/answers/677726661/)

  • 除了上面的内容之外,我还必须添加 edittext.clearFocus() 才能使其正常工作:) (2认同)

Ris*_*ena 51

最简单的答案,只需在XML的父布局中添加它.

android:focusable="true" 
android:focusableInTouchMode="true"
Run Code Online (Sandbox Code Playgroud)

  • 对我来说效果很好。还有一点要注意的是,不要将这些行添加到滚动视图中。它不会在滚动视图中工作。但与线性布局完美配合。 (2认同)

ral*_*lat 42

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

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud)

  • android:windowSoftInputMode ="adjustPan"对Android Manifest中的任何活动 (2认同)

小智 39

简单的解决办法:在AndroidManifestActivity标签使用

android:windowSoftInputMode="stateAlwaysHidden"
Run Code Online (Sandbox Code Playgroud)

  • 严格来说,这并不能解决问题.OP表示:"我不希望任何控制在启动时都有输入焦点." 您的解决方案只隐藏键盘,这是一个不同的区别. (6认同)

小智 34

你可以只设置"可聚焦""可聚焦在触摸模式"价值真正在第一TextViewlayout.通过这种方式,当活动开始时,TextView将集中注意力,但由于其性质,您将看不到任何焦点在屏幕上,当然,将不会显示键盘......


Bab*_*nah 33

以下为我工作Manifest.写,

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
Run Code Online (Sandbox Code Playgroud)

  • 这不会使文本字段失去焦点:它只是隐藏了键盘。你仍然会得到一个被推出字段的提示,任何颜色状态选择器都将显示“focused=true”状态。 (2认同)

jak*_*eff 29

我需要以编程方式清除所有字段的焦点.我刚刚在主要布局定义中添加了以下两个语句.

myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
myLayout.setFocusableInTouchMode(true);
Run Code Online (Sandbox Code Playgroud)

而已.马上解决了我的问题.谢谢,西尔弗,指出我正确的方向.


prg*_*Dev 26

添加文件android:windowSoftInputMode="stateAlwaysHidden"的活动标记Manifest.xml.

资源


Sid*_*Sid 22

如果您对活动有另一种观点,例如a ListView,您还可以:

ListView.requestFocus(); 
Run Code Online (Sandbox Code Playgroud)

在你onResume()的抓住焦点editText.

我知道这个问题已得到解答,但只提供了一个对我有用的替代解决方案:)


Vis*_*Raj 21

onCreate方法中添加以下内容

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Run Code Online (Sandbox Code Playgroud)

  • 这不会使文本字段失去焦点:它只是隐藏了键盘。你仍然会得到一个被推出字段的提示,任何颜色状态选择器都将显示“focused=true”状态。 (2认同)

小智 20

在第一个可编辑字段之前尝试此操作:

<TextView  
        android:id="@+id/dummyfocus" 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:text="@string/foo"
        />

----

findViewById(R.id.dummyfocus).setFocusableInTouchMode(true);
findViewById(R.id.dummyfocus).requestFocus();
Run Code Online (Sandbox Code Playgroud)


Tak*_*ion 17

由于我不喜欢用与功能相关的东西污染XML,我创建了这个方法,"透明地"从第一个可聚焦视图中窃取焦点,然后确保在必要时自行移除!

public static View preventInitialFocus(final Activity activity)
{
    final ViewGroup content = (ViewGroup)activity.findViewById(android.R.id.content);
    final View root = content.getChildAt(0);
    if (root == null) return null;
    final View focusDummy = new View(activity);
    final View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View view, boolean b)
        {
            view.setOnFocusChangeListener(null);
            content.removeView(focusDummy);
        }
    };
    focusDummy.setFocusable(true);
    focusDummy.setFocusableInTouchMode(true);
    content.addView(focusDummy, 0, new LinearLayout.LayoutParams(0, 0));
    if (root instanceof ViewGroup)
    {
        final ViewGroup _root = (ViewGroup)root;
        for (int i = 1, children = _root.getChildCount(); i < children; i++)
        {
            final View child = _root.getChildAt(i);
            if (child.isFocusable() || child.isFocusableInTouchMode())
            {
                child.setOnFocusChangeListener(onFocusChangeListener);
                break;
            }
        }
    }
    else if (root.isFocusable() || root.isFocusableInTouchMode())
        root.setOnFocusChangeListener(onFocusChangeListener);

    return focusDummy;
}
Run Code Online (Sandbox Code Playgroud)


小智 15

晚了,但也许有帮助.在创建布局的顶部的虚拟的EditText然后调用myDummyEditText.requestFocus()onCreate()

<EditText android:id="@+id/dummyEditTextFocus" 
android:layout_width="0px"
android:layout_height="0px" />
Run Code Online (Sandbox Code Playgroud)

这看起来像我期望的那样.不需要处理配置更改等.我需要这个用于具有冗长TextView(指令)的Activity.


mar*_*ark 13

是的,我做了同样的事情 - 创建一个'虚拟'线性布局,获得初始焦点.此外,我设置了"下一个"焦点ID,因此用户在滚动一次后无法再对焦:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());
Run Code Online (Sandbox Code Playgroud)

很多工作只是为了摆脱对视图的关注..

谢谢


Vis*_*nav 13

在父布局中写下这一行......

 android:focusableInTouchMode="true"
Run Code Online (Sandbox Code Playgroud)


and*_*per 12

对我来说,适用于所有设备的是:

    <!-- fake first focusable view, to allow stealing the focus to itself when clearing the focus from others -->

    <View
    android:layout_width="0px"
    android:layout_height="0px"
    android:focusable="true"
    android:focusableInTouchMode="true" />
Run Code Online (Sandbox Code Playgroud)

在有问题的焦点视图之前把它作为一个视图,就是这样.


小智 10

这是最完美,最简单的解决方案.我总是在我的应用程序中使用它.

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Run Code Online (Sandbox Code Playgroud)


小智 9

<TextView
    android:id="@+id/TextView01"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
    android:focusable="true"
    android:focusableInTouchMode="true"
    style="@android:style/Widget.EditText"/>
Run Code Online (Sandbox Code Playgroud)


Lum*_*mis 9

我做的最简单的事情是将焦点放在onCreate中的另一个视图上:

    myView.setFocusableInTouchMode(true);
    myView.requestFocus();
Run Code Online (Sandbox Code Playgroud)

这使得软键盘停止运行,EditText中没有光标闪烁.


Tar*_*Ray 8

写这里面的代码Manifest的文件Activity,你不想打开键盘.

android:windowSoftInputMode="stateHidden"
Run Code Online (Sandbox Code Playgroud)

清单文件:

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.projectt"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="24" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
         <activity
            android:name=".Splash"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Login"
            **android:windowSoftInputMode="stateHidden"**
            android:label="@string/app_name" >
        </activity>

    </application>

</manifest>
Run Code Online (Sandbox Code Playgroud)

  • 这不会取消文本字段的焦点:它只是隐藏键盘.你仍然会得到一个被推出场的提示,任何颜色状态选择器都会显示"focused = true"状态. (2认同)

Com*_*02x 7

onCreate您的Activity中,只需clearFocus()在EditText元素上添加use即可.例如,

edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();
Run Code Online (Sandbox Code Playgroud)

如果你想将焦点转移到另一个元素,请使用requestFocus()它.例如,

button = (Button) findViewById(R.id.button);
button.requestFocus();
Run Code Online (Sandbox Code Playgroud)


dre*_*i01 6

当我按下按钮时,我使用以下代码来阻止EditText窃取焦点.

addButton.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        View focused = internalWrapper.getFocusedChild();
        focused.setVisibility(GONE);
        v.requestFocus();
        addPanel();
        focused.setVisibility(VISIBLE);
    }
});
Run Code Online (Sandbox Code Playgroud)

基本上,隐藏编辑文本然后再次显示.这对我有用,因为EditText 不在视图中,所以它是否显示无关紧要.

您可以尝试隐藏并连续显示它,看看是否有助于它失去焦点.


Muh*_*Ali 6

确保"<requestFocus />"EditTextxml中的标记中删除该行.

<EditText
   android:id="@+id/input"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content">

   <requestFocus /> <!-- remove this line --> 
</EditText>
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以通过创建EditText布局宽度和高度设置为的虚拟对象来实现此目的0dp,并请求焦点到该视图.在xml布局中添加以下代码段:

<EditText
    android:id="@+id/editText0"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:hint="@string/dummy"
    android:ems="10" 
    >
     <requestFocus />
    </EditText>
Run Code Online (Sandbox Code Playgroud)


Man*_*... 6

当您的活动打开时,键盘会自动显示,从而导致EditText聚焦.您可以通过在manifest.xml文件的活动标记中写入以下行来禁用键盘.

 android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
Run Code Online (Sandbox Code Playgroud)


sha*_*mar 6

隐藏键盘的最简单方法是使用setSoftInputMode

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Run Code Online (Sandbox Code Playgroud)

或者您可以使用InputMethodManager并隐藏这样的键盘.

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
Run Code Online (Sandbox Code Playgroud)


DkP*_*hak 5

View current = getCurrentFocus();

if (current != null) 
    current.clearFocus();
Run Code Online (Sandbox Code Playgroud)


has*_*rza 5

你有Edittextlist。在 OnStart/On Create 中,您应该将焦点设置在列表视图上:listview.requestfocus()