如何在Android中防止活动启动时EditText获取焦点?

3161

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

  1. EditText
  2. ListView

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

EditText.setSelected(false);
EditText.setFocusable(false);

没有成功。我该如何说服EditTextActivity启动时不选择自己?

54个回答

20

由于我不喜欢在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;
}

18

虽然有些晚,但也许会有所帮助。在布局的顶部创建一个虚拟EditText,然后在onCreate()中调用myDummyEditText.requestFocus()

<EditText android:id="@+id/dummyEditTextFocus" 
android:layout_width="0px"
android:layout_height="0px" />

看起来这个行为符合我的预期。不需要处理配置更改等问题。我需要这个功能用于一个包含长文本视图(说明)的活动。


1
为什么不直接使用根视图自身来完成这个操作? - CJBS

17

是的,我也是这样做的 - 创建一个“虚拟”的线性布局,它获取了初始焦点。此外,我设置了“下一个”焦点ID,所以用户在滚动一次后就不能再将其聚焦了:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());
 
dummy.setNextFocusUpId(et.getId());
 
et.setNextFocusUpId(et.getId());

为了消除视图上的焦点,需要做很多工作。

谢谢


14
<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"/>

14

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

myView.setFocusableInTouchMode(true);
myView.requestFocus();

这样做可以阻止软键盘弹出,并且在EditText中不会闪烁光标。


14

对我来说,在所有设备上都有效的方法是这样的:

    <!-- 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" />

只需将此视图放在有问题的聚焦视图之前,就可以了。


12

这是最完美和最简单的解决方案。我总是在我的应用程序中使用它。
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);


1
这并不会取消焦点文本字段:它只是隐藏了键盘。您仍将获得从该字段中推出的提示,并且任何颜色状态选择器都将显示“focused=true”状态。 - A. Rager

11

将此代码写入位于您不想打开键盘的Activity中的Manifest文件中。

android:windowSoftInputMode="stateHidden"

清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.project"
    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>

3
这并不会取消文本框的焦点,仅仅是隐藏了键盘。你仍然可以看到被推出文本框的提示,并且任何颜色状态选择器都会显示“focused=true”状态。 - A. Rager

9
在您的活动的onCreate中,只需在EditText元素上使用clearFocus()。例如,
edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();

如果您想将焦点转移到另一个元素,请在该元素上使用requestFocus()。例如:

button = (Button) findViewById(R.id.button);
button.requestFocus();

9
最简单的隐藏键盘的方法是使用setSoftInputMode函数。
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

或者您可以使用InputMethodManager并像以下这样隐藏键盘。
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);

问题与键盘无关。 - Ricardo A.

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