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

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

  1. EditText
  2. ListView

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

 EditText.setSelected(false); 

没有运气。 如何说服EditTextActivity开始时不select自己?

来自Luc和Mark的优秀答案,但是缺less一个好的代码示例:

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

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

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

android:windowSoftInputMode="stateHidden" – input活动时总是隐藏它。

或者android:windowSoftInputMode="stateUnchanged" – 不要改变它(例如,如果它没有被显示,但是如果它在进入活动时打开,则不要显示它)。

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

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

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

感谢Guillaume。

我find的唯一解决scheme是:

  • 创build一个LinearLayout (我不知道如果其他种类的布局将工作)
  • 设置属性android:focusable="true"android:focusableInTouchMode="true"

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

问题似乎来自一个属性,我只能看到在布局的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> 

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

在布局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(); } 

以下内容将在创build时停止编辑对焦,但在触摸时抓住它。

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

因为你回复错误,即不消耗事件,聚焦行为将像正常一样进行。

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

我已经尝试了单独的答案,但重点仍然在EditText。 我只能通过使用上面的两个解决scheme来解决它。

 <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

这些解决scheme都没有为我工作。 我修复自动对焦的方式是:

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

简单的解决scheme:在AndroidManifest中使用Activity标签

 android:windowSoftInputMode="stateAlwaysHidden" 

您可以在layout的第一个TextView上设置“focusable”“focusable in touch mode”以将值设置为true。 通过这种方式,当活动开始时, TextView将被聚焦,但由于其本质,您将看不到任何焦点在屏幕上,当然,将显示键盘。

以下在Manifest为我工作。 写,

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

我需要通过编程清除所有领域的焦点。 我只是将以下两个语句添加到我的主布局定义。

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

而已。 立即解决了我的问题。 谢谢,银,指着我在正确的方向。

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

资源

在第一个可编辑字段之前试试这个:

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

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

 ListView.requestFocus(); 

在你的onResume()editText抓取焦点。

我知道这个问题已经回答,但只是提供了替代解决scheme,为我工作:)

onCreate方法中添加以下内容:

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

因为我不喜欢用某种与function相关的东西来污染XML,所以我创build了这种“透明”的方法,将焦点从第一个可聚焦视图中偷走,然后确保在必要时自行移除它!

 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; } 

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

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

这似乎performance得如我所料。 无需处理configuration更改等。我需要一个与一个冗长的TextView的活动(说明)。

是的,我做了同样的事情 – 创build一个“虚拟”线性布局,得到最初的重点。 此外,我设置“下一个”焦点ID,以便用户在滚动一次之后不能再聚焦:

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

很多工作只是为了摆脱焦点的观点..

谢谢

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

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

这样就停止了软键盘,EditText中没有光标闪烁。

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

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

只是把这个看作是有问题的重点观点之前的一个观点,就是这样。

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

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

在Activity的onCreate上,只需在EditText元素上添加使用clearFocus() 。 例如,

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

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

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

您可以通过创build一个虚拟的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> 

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

 <EditText android:id="@+id/input" android:layout_width="fill_parent" android:layout_height="wrap_content"> <requestFocus /> <!-- remove this line --> </EditText> 
 <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"/> 

我使用下面的代码来阻止EditText在按下button时窃取焦点。

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

基本上,隐藏编辑文本,然后再显示它。 这适用于我,因为EditText 不在视图中,所以它是否显示并不重要。

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

 /** * 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); } } }