10

在我的应用程序中,我正在制作一个搜索界面,其中在SearchView失去焦点和获得焦点时分别折叠和展开。然而,失去焦点的事情只发生在两种情况下:

  1. 当按下返回按钮时。

  2. SearchView按下旁边的主页图标时。

如果用户不仅点击这两个东西,而且点击屏幕上的任何其他地方(例如,任何按钮或屏幕上没有视图的任何空白部分),我希望它失去焦点(并因此崩溃)。

4

4 回答 4

10

好吧,我找到了以下解决方案。我在不是 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);
        }
    }
}

是我提到的答案。

于 2013-07-11T10:55:23.463 回答
2

好吧,我有另一种更简单、更整洁的方法。如果您将搜索小部件用作工具栏中的操作视图 ( 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);
}

就是这样!希望这对未来的读者有用:)

于 2018-08-02T04:04:28.707 回答
1

就我而言,每当用户单击任何其他视图时,我都必须停止搜索并关闭键盘,这对我有用。

    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);
}
于 2019-12-06T17:01:39.797 回答
0

这对我有用,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);
}
于 2015-04-24T20:53:14.517 回答