私のアプリでは、フォーカスを失ったときとフォーカスを取得したときにそれぞれ折りたたんで展開する検索インターフェイスを作成しています。SearchView
ただし、フォーカスが失われるのは次の 2 つの場合のみです。
戻るボタンを押したとき。
横のホームアイコン
SearchView
を押したとき。
ユーザーがこれら2つのものだけでなく、画面上の他の場所(たとえば、ボタンやビューのない画面の空白部分)をクリックすると、フォーカスが失われます(したがって、折りたたまれます)。
私のアプリでは、フォーカスを失ったときとフォーカスを取得したときにそれぞれ折りたたんで展開する検索インターフェイスを作成しています。SearchView
ただし、フォーカスが失われるのは次の 2 つの場合のみです。
戻るボタンを押したとき。
横のホームアイコンSearchView
を押したとき。
ユーザーがこれら2つのものだけでなく、画面上の他の場所(たとえば、ボタンやビューのない画面の空白部分)をクリックすると、フォーカスが失われます(したがって、折りたたまれます)。
さて、私は次の解決策を見つけました。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 のフォーカスを失い、ユーザーが画面上の他の場所に触れたときのキーボード。
SearchView には AutoCompleteTextView があるため、SearhView を除く階層内のすべてのビューでタッチ リスナーを繰り返し設定する代わりに、このソリューションを簡単に利用できます。
ステップ 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);
}