如何在不将焦点设置为其他控件的情况下移除焦点?

我喜欢我的 UI 是直观的; 每个屏幕应该自然而不引人注目地引导用户进入应用程序的下一步。除此之外,我努力让事情变得尽可能混乱。

开玩笑的: -)

我有三个 TableRow,每个包含一个只读和不可聚焦的 EditText 控件,然后在其右侧有一个按钮。每个按钮启动相同的活动,但使用不同的参数。用户在那里进行选择,子活动完成,用用户的选择填充适当的 EditText

这是典型的级联值机制; 每个选择都缩小了下一个选择的可用选项,等等。因此,在当前行上的 EditText 包含一个值之前,我将禁用接下来每一行上的两个控件。

我需要做两件事中的一件,按照这个优先顺序:

  1. 当单击一个按钮时,立即删除焦点,而不将焦点设置为另一个按钮
  2. Set focus to the first button when the activity starts

问题在子活动返回后显示; 单击的按钮保持焦点。

回复: # 1以上-似乎没有一个 removeFocus()方法,或类似的东西

Re: #2 above - I can use requestFocus() to set focus to the button on the next row, and that works after the sub-activity returns, but for some reason it doesn't work in the parent activity's onCreate().

我需要 UI 在两个方向上的一致性——要么在子活动结束后没有按钮获得焦点,要么每个按钮获得焦点取决于它在逻辑流中的位置,包括在任何选择之前的第一个(也是唯一的)活动按钮。

148541 次浏览

使用 clearFocus ()似乎对我也不起作用,就像你发现的那样(从对另一个答案的评论中可以看到) ,但最终对我起作用的是添加:

<LinearLayout
android:id="@+id/my_layout"
android:focusable="true"
android:focusableInTouchMode="true" ...>

to my very top level Layout View (a linear layout). To remove focus from all Buttons/EditTexts etc, you can then just do

LinearLayout myLayout = (LinearLayout) activity.findViewById(R.id.my_layout);
myLayout.requestFocus();

除非我将视图设置为可调焦,否则请求焦点没有任何作用。

  1. 你可以使用 View.clearFocus()

  2. 使用从 onResume()调用的 View.requestFocus()

您可以尝试关闭主活动保存其状态的功能(从而使其忘记哪个控件有文本,哪个控件有焦点)。您需要使用其他方法来记住 EditText 的内容并在 Resume ()上重新填充它们。使用 startActivityForResult ()启动子活动,并在主活动中创建一个 onActivityResult ()处理程序,该处理程序将正确更新 EditText 的。通过这种方式,您可以在使用 myButton.post (new Runnable (){ run (){ myButton.requestFocus () ; }})重新填充 EditText 的同时,设置您希望聚焦在 Resume ()上的正确按钮;

Post ()方法对于最初设置焦点非常有用,因为在创建窗口和事情平静下来之后,将执行可运行的程序,从而允许焦点机制在那个时候正常运行。我发现,试图在 onCreate/Start/Resume ()期间设置焦点通常会有问题。

请注意,这是伪代码,未经测试,但它是一个可能的方向,您可以尝试。

Old question, but I came across it when I had a similar issue and thought I'd share what I ended up doing.

每次获得关注的观点都不同,因此我使用了非常一般的观点:

View current = getCurrentFocus();
if (current != null) current.clearFocus();

在清单中的活动中添加 android:windowSoftInputMode="stateHidden"怎么样。

摘自一位聪明人的评论: https://stackoverflow.com/a/2059394/956975

首先,它将100% 的工作... ..。

  1. 创建 onResume()方法。
  2. 在这个 onResume()内部找到的观点是一次又一次的聚焦由 findViewById()
  3. 在这个 onResume()设置 requestFocus()到这个视图。
  4. 在这个 onResume()设置 clearFocus到这个视图。
  5. 进入相同布局的 xml 中,找到您想要聚焦的顶部视图,并设置 focusable true 和 focusableInTuch true。
  6. 在这个 onResume()找到以上由 findViewById俯视图
  7. 在这个 onResume()设置 requestFocus()到这个视图在最后。
  8. 现在请欣赏..。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/ll_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


LinearLayout llRootView = findViewBindId(R.id.ll_root_view);
llRootView.clearFocus();

我使用此时已经完成更新配置文件信息和删除所有的焦点从我的布局 EditText

= = = > 更新: 在父布局内容中,我的 EditText 添加一行:

android:focusableInTouchMode="true"

我尝试禁用和启用视图的可聚焦性,它对我很有效(重置了焦点) :

focusedView.setFocusable(false);
focusedView.setFocusableInTouchMode(false);
focusedView.setFocusable(true);
focusedView.setFocusableInTouchMode(true);
android:focusableInTouchMode="true"
android:focusable="true"
android:clickable="true"

Add them to your ViewGroup that includes your EditTextView. 它对我的约束布局工作正常。希望这有所帮助

android:descendantFocusability="beforeDescendants"

在活动中使用下面的内容和下面的一些布局选项似乎可以达到预期的效果。

 getWindow().getDecorView().findViewById(android.R.id.content).clearFocus();

in connection with the following parameters on the root view.

<?xml
android:focusable="true"
android:focusableInTouchMode="true"
android:descendantFocusability="beforeDescendants" />

Https://developer.android.com/reference/android/view/viewgroup#attr_android:descendantfocusability

回答感谢: https://forums.xamarin.com/discussion/1856/how-to-disable-auto-focus-on-edit-text

关于 windowSoftInputMode

还有一点需要注意,默认情况下, Android 会自动将初始焦点分配给第一个 EditText 或者在你的活动中有可定焦的控制 InputMethod (通常是软键盘)将响应焦点 中的 windowSoftInputMode 属性 当设置为 stateAlwaysHidden 时,AndroidManifest.xml 指示 键盘忽略此自动分配的初始焦点。

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

很好的参考

尝试以下操作(调用 clearAllEditTextFocuses();)

private final boolean clearAllEditTextFocuses() {
View v = getCurrentFocus();
if(v instanceof EditText) {
final FocusedEditTextItems list = new FocusedEditTextItems();
list.addAndClearFocus((EditText) v);


//Focus von allen EditTexten entfernen
boolean repeat = true;
do {
v = getCurrentFocus();
if(v instanceof EditText) {
if(list.containsView(v))
repeat = false;
else list.addAndClearFocus((EditText) v);
} else repeat = false;
} while(repeat);


final boolean result = !(v instanceof EditText);
//Focus wieder setzen
list.reset();
return result;
} else return false;
}


private final static class FocusedEditTextItem {


private final boolean focusable;


private final boolean focusableInTouchMode;


@NonNull
private final EditText editText;


private FocusedEditTextItem(final @NonNull EditText v) {
editText = v;
focusable = v.isFocusable();
focusableInTouchMode = v.isFocusableInTouchMode();
}


private final void clearFocus() {
if(focusable)
editText.setFocusable(false);
if(focusableInTouchMode)
editText.setFocusableInTouchMode(false);
editText.clearFocus();
}


private final void reset() {
if(focusable)
editText.setFocusable(true);
if(focusableInTouchMode)
editText.setFocusableInTouchMode(true);
}


}


private final static class FocusedEditTextItems extends ArrayList<FocusedEditTextItem> {


private final void addAndClearFocus(final @NonNull EditText v) {
final FocusedEditTextItem item = new FocusedEditTextItem(v);
add(item);
item.clearFocus();
}


private final boolean containsView(final @NonNull View v) {
boolean result = false;
for(FocusedEditTextItem item: this) {
if(item.editText == v) {
result = true;
break;
}
}
return result;
}


private final void reset() {
for(FocusedEditTextItem item: this)
item.reset();
}


}

您不需要清除焦点,只需在需要焦点的地方添加此代码

 time_statusTV.setFocusable(true);
time_statusTV.requestFocus();
InputMethodManager imm = (InputMethodManager)this.getSystemService(Service.INPUT_METHOD_SERVICE);
imm.showSoftInput( time_statusTV, 0);