在我的应用程序中,我正在制作一个搜索界面,其中在SearchView
失去焦点和获得焦点时分别折叠和展开。然而,失去焦点的事情只发生在两种情况下:
当按下返回按钮时。
当
SearchView
按下旁边的主页图标时。
如果用户不仅点击这两个东西,而且点击屏幕上的任何其他地方(例如,任何按钮或屏幕上没有视图的任何空白部分),我希望它失去焦点(并因此崩溃)。
在我的应用程序中,我正在制作一个搜索界面,其中在SearchView
失去焦点和获得焦点时分别折叠和展开。然而,失去焦点的事情只发生在两种情况下:
当按下返回按钮时。
当SearchView
按下旁边的主页图标时。
如果用户不仅点击这两个东西,而且点击屏幕上的任何其他地方(例如,任何按钮或屏幕上没有视图的任何空白部分),我希望它失去焦点(并因此崩溃)。
好吧,我找到了以下解决方案。我在不是 searchview 实例的每个视图上都使用了 setOnTouchListener 来折叠 searchview。它对我来说很完美。以下是代码。
public void setupUI(View view) {
if(!(view instanceof SearchView)) {
view.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
searchMenuItem.collapseActionView();
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
这是我提到的答案。
好吧,我有另一种更简单、更整洁的方法。如果您将搜索小部件用作工具栏中的操作视图 ( https://developer.android.com/guide/topics/search/search-dialog#UsingSearchWidget ),您可能希望使 SearchView 失去焦点并隐藏当用户触摸屏幕上其他任何地方时的键盘。
无需在除 SearhView 之外的层次结构中的每个视图上迭代和设置触摸侦听器,您只需使用此解决方案即可,因为 SearchView 中有一个 AutoCompleteTextView。
第 1 步:通过添加以下属性使父视图(活动的内容视图)可点击和可聚焦
android:clickable="true"
android:focusableInTouchMode="true"
第 2 步:在 SearchView AutoCompleteTextView 上设置 OnFocusChangeListener
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
final MenuItem search = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) search.getActionView();
// get a reference of the AutoCompleteTextView from the searchView
AutoCompleteTextView searchSrcText = searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
searchSrcText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
});
return super.onCreateOptionsMenu(menu);
}
就是这样!希望这对未来的读者有用:)
就我而言,每当用户单击任何其他视图时,我都必须停止搜索并关闭键盘,这对我有用。
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View view = getCurrentFocus();
if (view != null && view instanceof EditText) {
Rect r = new Rect();
view.getGlobalVisibleRect(r);
int rawX = (int) ev.getRawX();
int rawY = (int) ev.getRawY();
if (!r.contains(rawX, rawY)) {
hideSoftKeyboard(MainActivity.this);
}
}
}
return super.dispatchTouchEvent(ev);
}
这对我有用,mOptionsMenu 保存在 onCreateOptionsMenu 中:
public void setupUI(View view) {
//Set up touch listener for non-text box views to hide keyboard.
if(!(view instanceof EditText)) {
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard(MainActivity.this);
if(mOptionsMenu == null) return false;
MenuItem searchMenuItem = mOptionsMenu.findItem(R.id.action_search);
if(searchMenuItem == null) return false;
((SearchView)searchMenuItem.getActionView()).clearFocus();
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}