Stop EditText from gaining focus at Activity startup
我在Android中有一个
当我的
1 | EditText.setSelected(false); |
运气不好。我怎样才能说服
Luc和Mark给出了很好的答案,但是缺少了一个好的代码示例。像下面的例子一样,将标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!-- 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"/> |
你真的不想让它集中注意力吗?或者您不希望它在聚焦
如果是虚拟键盘的问题,请参阅
或者
存在一个更简单的解决方案。在父布局中设置这些属性:
1 2 3 4 | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLayout" android:descendantFocusability="beforeDescendants" android:focusableInTouchMode="true"> |
现在,当活动开始时,默认情况下,主布局将获得焦点。
此外,我们还可以在运行时(例如,完成子级编辑后)将焦点从子视图中移除,方法是再次将焦点放在主布局上,如下所示:
1 | findViewById(R.id.mainLayout).requestFocus(); |
来自Guillaume Perrot的好评:
android:descendantFocusability="beforeDescendants" seems to be the
default (integer value is 0). It works just by adding
android:focusableInTouchMode="true" .
实际上,我们可以看到
多亏了桂林。
我找到的唯一解决方案是:
- 创建一个线性布局(如果其他类型的布局有效,我不知道)
- 设置属性
android:focusable="true" 和android:focusableInTouchMode="true" 。
而
问题似乎来自一个我只能在布局的
确保在
1 | <requestFocus /> |
应该是这样的:
1 2 3 4 5 6 7 8 | <EditText android:id="@+id/emailField" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress"> //<requestFocus /> /* <-- without this line */ </EditText> |
使用其他海报提供的信息,我使用了以下解决方案:
在布局XML中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!-- 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"/> |
在OnCeRead()中
1 2 3 4 5 6 7 8 9 10 11 12 | 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()中
1 2 3 4 5 6 7 8 | @Override protected void onResume() { super.onResume(); //do not give the editbox focus automatically when activity starts mAutoCompleteTextView.clearFocus(); mLinearLayout.requestFocus(); } |
尝试clearFocus()而不是
以下内容将阻止EditText在创建时获得焦点,但在触摸它们时将其抓取。
1 2 3 | <EditText android:id="@+id/et_bonus_custom" android:focusable="false" /> |
因此,您在XML中设置了可聚焦到false,但是该键位于Java中,您添加了以下监听器:
1 2 3 4 5 6 7 8 | etBonus.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { v.setFocusable(true); v.setFocusableInTouchMode(true); return false; } }); |
因为你返回错误,即不消耗事件,聚焦行为将像正常一样进行。
我试过几个答案,但重点仍然在编辑文本上。我只能通过同时使用下面的两个解决方案来解决这个问题。
1 2 3 4 | <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)
去除
1 | <requestFocus /> |
在EditText
(参考来自FloydAddict https://stackoverflow.com/a/9681809)
这些解决方案对我都不起作用。我修复自动对焦的方法是:
1 2 3 | <intent-filter > </intent-filter> </activity> |
简单解决方案:在
1 | android:windowSoftInputMode="stateAlwaysHidden" |
您只需将"Focusable"和"Focusable in Touch Mode"设置为在
以下是我在
1 2 3 | <activity android:name=".MyActivity" android:windowSoftInputMode="stateAlwaysHidden"/> |
最简单的答案是,只需将其添加到XML的父布局中。
1 2 | android:focusable="true" android:focusableInTouchMode="true" |
我需要以编程方式从所有字段中清除焦点。我刚刚将以下两条语句添加到我的主布局定义中。
1 2 | myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); myLayout.setFocusableInTouchMode(true); |
就是这样。立即解决了我的问题。谢谢,西尔弗,你指点我的方向。
在
来源
如果您对自己的活动有另一种看法,如
1 | ListView.requestFocus(); |
在你的
我知道这个问题已经得到了解答,但只是提供了一个对我有用的替代解决方案:)
在第一个可编辑字段之前尝试此操作:
1 2 3 4 5 6 7 8 9 10 11 | <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(); |
在
1 | this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); |
由于我不喜欢用与功能相关的东西污染XML,所以我创建了一个方法,它"透明地"从第一个可聚焦视图中窃取焦点,然后确保在必要时将其自身移除!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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; } |
晚了,但可能会有帮助。在布局顶部创建一个虚拟的edittext,然后在
1 2 3 | <EditText android:id="@+id/dummyEditTextFocus" android:layout_width="0px" android:layout_height="0px" /> |
这似乎和我期望的一样。不需要处理配置更改等。对于具有长文本视图(说明)的活动,我需要这样做。
是的,我做了同样的事情-创建一个"虚拟"的线性布局,得到初始焦点。此外,我还设置了"下一个"焦点ID,这样用户在滚动一次之后就不能再聚焦它了:
1 2 3 4 5 6 7 8 | <LinearLayout 'dummy'> <EditText et> dummy.setNextFocusDownId(et.getId()); dummy.setNextFocusUpId(et.getId()); et.setNextFocusUpId(et.getId()); |
很多工作只是为了摆脱对视图的关注。
谢谢
在父布局中编写此行…
1 | android:focusableInTouchMode="true" |
对我来说,所有设备的工作原理是:
1 2 3 4 5 6 7 | <!-- 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" /> |
把它作为一个视图放在有问题的焦点视图之前,就是这样。
这是最完美和最简单的解决方案。我总是在我的应用程序中使用它。
1 | getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); |
我做的最简单的事情是在OnCreate中将焦点放在另一个视图上:
1 2 | myView.setFocusableInTouchMode(true); myView.requestFocus(); |
这停止了软键盘的出现,编辑文本中没有光标闪烁。
1 2 3 4 5 6 7 8 9 10 11 | <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"/> |
在不想打开键盘的
1 | android:windowSoftInputMode="stateHidden" |
清单文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?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> <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> |
在活动的EDOCX1[0]处,只需在editText元素上添加use EDOCX1[1]。例如,
1 2 | edittext = (EditText) findViewById(R.id.edittext); edittext.clearFocus(); |
如果你想把注意力转移到另一个元素上,可以使用
1 2 | button = (Button) findViewById(R.id.button); button.requestFocus(); |
您可以通过创建一个布局宽度和高度设置为
1 2 3 4 5 6 7 8 9 | <EditText android:id="@+id/editText0" android:layout_width="0dp" android:layout_height="0dp" android:hint="@string/dummy" android:ems="10" > <requestFocus /> </EditText> |
当您的活动打开时,键盘会自动显示,这会导致EditText聚焦。您可以通过在manifest.xml文件的活动标记中写入以下行来禁用键盘。
1 | android:windowSoftInputMode="stateAlwaysHidden|adjustPan" |
隐藏键盘的最简单方法是使用setSoftInputMode
1 | getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); |
或者您可以使用inputmethodmanager并像这样隐藏键盘。
1 2 | InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0); |
确保从XML中的
1 2 3 4 5 6 7 | <EditText android:id="@+id/input" android:layout_width="fill_parent" android:layout_height="wrap_content"> <requestFocus /> <!-- remove this line --> </EditText> |
我使用下面的代码来阻止编辑文本在按下按钮时窃取焦点。
1 2 3 4 5 6 7 8 9 | addButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { View focused = internalWrapper.getFocusedChild(); focused.setVisibility(GONE); v.requestFocus(); addPanel(); focused.setVisibility(VISIBLE); } }); |
基本上,隐藏编辑文本,然后再次显示。这对我很有用,因为EditText不在视图中,所以它是否显示并不重要。
你可以试着连续隐藏和展示它,看看这是否有助于它失去焦点。
1 2 3 4 | View current = getCurrentFocus(); if (current != null) current.clearFocus(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /** * 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); } } } |
尝试
1 2 3 | edit.setInputType(InputType.TYPE_NULL); edit.setEnabled(false); |
最简单的方法是在manifest.xml文件的activity标签中添加
Disable it in onCreate()
1 2 3 | final KeyListener edtTxtMessageKeyListener = edtTxtMessage.getKeyListener(); edtTxtMessage.setCursorVisible(false); edtTxtMessage.setKeyListener(null); |
And finally enable it in onClick() of EditText
1 2 | edtTxtMessage.setCursorVisible(true); edtTxtMessage.setKeyListener(edtTxtMessageKeyListener); |
但问题是,我们必须点击twise,第一次把屏幕键盘带上。
@解决办法
1 2 | InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0); |
也可以在onclick()中尝试此操作:()
我遇到了这样的问题,这是由于我的选择。第一个状态是焦点,即使我的视图被禁用了,它也采用焦点状态,因为它是第一个匹配并使用它的状态。您可以将第一个状态设置为禁用,如下所示:
1 2 3 4 5 6 | <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文件中的编辑文本中删除ve
1 2 3 4 5 6 7 8 | <EditText android:id="@+id/emailField" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress"> //`<requestFocus />` /* <-- remove this tags */ </EditText>` |
1 2 3 4 5 6 7 8 9 10 | <EditText android:layout_width="match_parent" android:layout_height="100dp" android:id="@+id/etComments" android:hint="Comments.." android:textSize="14dp" android:focusable="false" android:textStyle="italic"/> |
做这件事,完成你的工作!
1 2 | android:focusable="true" android:focusableInTouchMode="true" |
您有编辑文本和列表。在OnStart/OnCreate中,您应该将焦点设置在列表视图:
通过使用请求焦点和键盘隐藏代码,可以将焦点指定给其他小部件。
它可以通过继承
1 2 3 4 5 6 7 8 9 10 | 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 } } |
然后您可以在布局中使用它,如Normal
1 2 3 4 5 6 7 | <com.yourpackage.NonFocusableEditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/your_hint" android:imeOptions="actionDone" android:inputType="textNoSuggestions" /> |
在清单文件的下面一行添加您提到的活动
1 | android:windowSoftInputMode="stateAlwaysHidden" |