停止EditText在Activity启动时获得焦点
我有一个Android Activity
,有两个元素:
-
EditText
-
ListView
当我的Activity
开始时, EditText
立即有input焦点(闪烁的光标)。 我不希望任何控件在启动时有input焦点。 我试过了:
EditText.setSelected(false);
没有运气。 如何说服EditText
在Activity
开始时不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); } } }