如何阻止EditText获得焦点,当一个活动开始在Android?

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

  1. EditText
  2. ListView

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

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

不走运。我怎样才能说服EditTextActivity开始时不选择自己?

810997 次浏览

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

我找到的唯一解决方案是:

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

并且EditText在开始活动后不会获得焦点

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

<LinearLayout 'dummy'><EditText et>
dummy.setNextFocusDownId(et.getId()); 
dummy.setNextFocusUpId(et.getId()); 
et.setNextFocusUpId(et.getId());

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

谢了

将标签android:focusableInTouchMode="true"android:focusable="true"添加到父布局(例如LinearLayoutConstraintLayout),如以下示例所示,将解决问题。

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus --><LinearLayoutandroid:focusable="true"android:focusableInTouchMode="true"android:layout_width="0px"android:layout_height="0px"/>
<!-- :nextFocusUp and :nextFocusLeft have been set to the id of this componentto 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"/>

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

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

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

或者android:windowSoftInputMode="stateUnchanged"-不要更改它(例如,如果它还没有显示,不要节目它,但如果它在进入活动时是打开的,让它保持打开)。

尝试

edit.setInputType(InputType.TYPE_NULL);
edit.setEnabled(false);

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

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

这似乎符合我的预期。不需要处理配置更改等。我需要一个带有冗长TextView(说明)的活动。

我使用以下代码来阻止EditText在按下按钮时窃取焦点。

addButton.setOnClickListener(new OnClickListener() {public void onClick(View v) {View focused = internalWrapper.getFocusedChild();focused.setVisibility(GONE);v.requestFocus();addPanel();focused.setVisibility(VISIBLE);}});
Basically, hide the edit text and then show it again. This works for me as the EditText is **not** in view so it doesn't matter whether it is showing.
You could try hiding and showing it in succession to see if that helps it lose focus.

如果你对你的活动有另一个视图,比如ListView,你也可以这样做:

ListView.requestFocus();

在你的onResume()中从editText中获取焦点。

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

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

在布局XML

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus --><LinearLayoutandroid:id="@+id/linearLayout_focus"android:focusable="true"android:focusableInTouchMode="true"android:layout_width="0px"android:layout_height="0px"/>
<!-- AUTOCOMPLETE --><AutoCompleteTextViewandroid: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;
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.mylayout);
//get references to UI componentsmAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete);mLinearLayout = (LinearLayout) findViewById(R.id.linearLayout_focus);}

最后,在onResume()中

@Overrideprotected void onResume() {super.onResume();
//do not give the editbox focus automatically when activity startsmAutoCompleteTextView.clearFocus();mLinearLayout.requestFocus();}

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

<TextViewandroid: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();

您可以将“可聚焦”"在触摸模式下可聚焦"设置为layout的第一个TextView上的值true。这样,当活动开始时,TextView将被聚焦,但是,由于其性质,您将在屏幕上看不到任何焦点,当然,将显示键盘…

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

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

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

<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();

评论不错纪尧姆·佩罗

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

实际上,我们可以看到beforeDescendantsViewGroup.initViewGroup()方法(Android 2.2.2)中被设置为默认值。但不等于0。ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

感谢纪尧姆。

<TextViewandroid: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"/>

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

确保在EditText XML标记中删除声明末尾的这一行:

<requestFocus />

这应该是这样的:

<EditTextandroid:id="@+id/emailField"android:layout_width="fill_parent"android:layout_height="wrap_content"android:inputType="textEmailAddress">
//<requestFocus /> /* <-- without this line */</EditText>

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

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

所以你在xml中设置可聚焦为false,但键在java中,你添加以下侦听器:

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

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

我需要以编程方式清楚地关注所有字段。我只是在我的主要布局定义中添加了以下两个语句。

myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);myLayout.setFocusableInTouchMode(true);

就这样。立刻解决了我的问题。谢谢,西尔弗,为我指明了正确的方向。

我已经分别尝试了几个答案,但焦点仍然在EditText上。我只能通过同时使用以下两个解决方案来解决它。

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

(来自Silverhttps://stackoverflow.com/a/8639921/15695

并删除

<requestFocus />

在edittext

(参考floydaddicthttps://stackoverflow.com/a/9681809

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

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

这阻止了软键盘的出现,并且EditText中没有光标闪烁。

因为我不喜欢用与功能相关的东西污染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(){@Overridepublic 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;}

在活动的onCreate处,只需在EditText元素上添加useclearFocus()。例如,

edittext = (EditText) findViewById(R.id.edittext);edittext.clearFocus();

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

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

确保从xml中的EditText标记中删除"<requestFocus />"行。

<EditTextandroid:id="@+id/input"android:layout_width="fill_parent"android:layout_height="wrap_content">
<requestFocus /> <!-- remove this line --></EditText>

ListView中的EditText不能正常工作。当您使用EditText时,最好将TableLayout与自动生成的行一起使用。

您可以使用请求焦点将焦点指定给其他小部件,也可以使用键盘隐藏代码。

简单的解决方案:在AndroidManifestActivity标签中使用

android:windowSoftInputMode="stateAlwaysHidden"

以下内容在Manifest中为我工作。写,

<activityandroid:name=".MyActivity"android:windowSoftInputMode="stateAlwaysHidden"/>

对我来说,在所有设备上工作的是:

    <!-- fake first focusable view, to allow stealing the focus to itself when clearing the focus from others -->
<Viewandroid:layout_width="0px"android:layout_height="0px"android:focusable="true"android:focusableInTouchMode="true" />

把这个作为一个视图放在有问题的聚焦视图之前,就是这样。

在onCreate()中禁用它

final KeyListener edtTxtMessageKeyListener = edtTxtMessage.getKeyListener();edtTxtMessage.setCursorVisible(false);edtTxtMessage.setKeyListener(null);

最后在EditText的onClick()中启用它

edtTxtMessage.setCursorVisible(true);edtTxtMessage.setKeyListener(edtTxtMessageKeyListener);

但问题是,我们必须点击twise才能第一次带来OnScreenKeyboard。

@解决方法

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

在onClick()中也试试这个:)

我有这样的问题,这是由于我的选择器。第一个状态是焦点,即使我的视图被禁用,它也采用了焦点状态,因为它是第一个匹配并使用它的状态。你可以像这样将第一个状态设置为禁用:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/text_field_disabled" android:state_enabled="false"/><item android:drawable="@drawable/text_field_focused" android:state_focused="true"/><item android:drawable="@drawable/text_field_normal"/>

xml文件中的EditText中删除<requestFocus />

<EditTextandroid:id="@+id/emailField"android:layout_width="fill_parent"android:layout_height="wrap_content"android:inputType="textEmailAddress">    
//`<requestFocus />` /* <-- remove this tags */</EditText>

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

<EditTextandroid:layout_width="match_parent"android:layout_height="100dp"android:id="@+id/etComments"android:hint="Comments.."android:textSize="14dp"android:focusable="false"android:textStyle="italic"/>

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

<EditTextandroid:id="@+id/editText0"android:layout_width="0dp"android:layout_height="0dp"android:hint="@string/dummy"android:ems="10"><requestFocus /></EditText>

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

源代码

/*** set focus to top level window* disposes descendant focus* disposes softInput* */public static void topLevelFocus(Context context){if(Activity.class.isAssignableFrom(context.getClass())){ViewGroup tlView = (ViewGroup) ((Activity) context).getWindow().getDecorView();if(tlView!=null){tlView.setFocusable(true);tlView.setFocusableInTouchMode(true);tlView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);}}}

onCreate方法中添加以下内容:

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

最简单的方法是在Manifest.xml文件的活动标签中添加android:windowSoftInputMode="stateAlwaysHidden"

将此代码写入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-sdkandroid:minSdkVersion="8"android:targetSdkVersion="24" />
<applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid: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><activityandroid:name=".Login"**android:windowSoftInputMode="stateHidden"**android:label="@string/app_name" ></activity> 
</application>
</manifest>
View current = getCurrentFocus();
if (current != null)current.clearFocus();

做这件事,完成你的工作!

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

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

android:windowSoftInputMode="stateAlwaysHidden|adjustPan"

在你的父布局中写下这一行…

 android:focusableInTouchMode="true"

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

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

或者,您可以使用InputmododManager并像这样隐藏键盘。

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);

迟来但最简单的答案,只需将其添加到XML的父布局中即可。

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

如果对你有帮助,请投票!编码快乐:)

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

它可以通过继承EditText和覆盖onTouchEvent来实现。

class NonFocusableEditText: EditText {
constructor(context: Context): super(context)constructor(context: Context, attrs: AttributeSet?): super(context, attrs)constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)
override fun onTouchEvent(event: MotionEvent?): Boolean {return if (isFocusable) super.onTouchEvent(event) else false}}

然后你可以像普通的EditText一样在布局中使用它:

<com.yourpackage.NonFocusableEditTextandroid:id="@+id/editText"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="@string/your_hint"android:imeOptions="actionDone"android:inputType="textNoSuggestions" />

在清单文件中添加以下行,您在其中提到了您的活动

android:windowSoftInputMode="stateAlwaysHidden"

如果您想在活动开始时隐藏键盘。然后提到

android:windowSoftInputMode="stateHidden"

到清单文件中的该活动。问题得到解决。

干杯。

我用提交按钮清除所有焦点

xml文件:

<LinearLayout...android:id="@+id/linear_layout"android:focusableInTouchMode="true"> // 1. make this focusableInTouchMode...</LinearLayout>

java文件:

private LinearLayout mLinearLayout; // 2. parent layout elementprivate Button mButton;
mLinearLayout = findViewById(R.id.linear_layout);mButton = findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mLinearLayout.requestFocus(); // 3. request focus
}});

希望对你有帮助:)

一个简单可靠的解决方案,只需覆盖此方法:

@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {View v = getCurrentFocus();
if (v != null &&(ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) &&v instanceof EditText &&!v.getClass().getName().startsWith("android.webkit.")) {int scrcoords[] = new int[2];v.getLocationOnScreen(scrcoords);float x = ev.getRawX() + v.getLeft() - scrcoords[0];float y = ev.getRawY() + v.getTop() - scrcoords[1];
if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom())hideKeyboard(this);}return super.dispatchTouchEvent(ev);}
public static void hideKeyboard(Activity activity) {if (activity != null && activity.getWindow() != null && activity.getWindow().getDecorView() != null) {InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);}}

只需在EditText的父布局中添加android:focusableInTouchMode="true",您将摆脱这种尴尬的行为。

已经提供了很多工作答案,但我认为我们可以通过使用下面的简单方法做得更好

//set focus to input fieldprivate fun focusHere() {findViewById<TextView>(R.id.input).requestFocus()}

代替输入R.id.input使用任何其他视图ID将焦点设置为该视图。

您可以将Edittext设置为禁用焦点属性,现在这可以通过两种方式应用:

  • 您可以禁用可聚焦作为一般属性

  • 或者您可以在触摸模式(触摸屏)下禁用特定于该视图的属性。

默认情况下,可聚焦属性为true,如果Edittext位于该活动中视图堆栈的顶部,例如标头,它将在活动启动时可聚焦。

要禁用可聚焦,您只需将其布尔值设置为false。

所以这将是:

android:focusable="false"

要禁用它,您可以简单地将其布尔值设置为false。这将是:

android:focusable="false"

您只需找到要应用更改的Textview,并将相应的代码片段添加到XML文件中的xml规范中。

或者,您可以单击布局编辑器中的Textview并找到显示该Textview的所有xml属性的侧边栏,然后只需向下滚动到声明“可聚焦”和“可聚焦InTouchMode”的位置并检查它们是否为真或假。