如何在单击其他活动时使SearchView失去焦点并崩溃

时间:2013-07-11 10:20:44

标签: java android searchview

在我的应用中,我正在制作search interface SearchView,当SearchView失去并分别获得焦点时,{{1}}会崩溃并展开。然而,失去焦点的事情只发生在两种情况下:

  1. 按下后退按钮时。

  2. 按下{{1}}旁边的主页图标时。

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

4 个答案:

答案 0 :(得分:8)

我发现了以下解决方案。我在每个不是searchview实例的视图上使用了setOnTouchListener来折叠搜索视图。它对我来说很完美。以下是代码。

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);
        }
    }
}

This就是我提到的答案。

答案 1 :(得分: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);
}

答案 2 :(得分:0)

好吧,我还有另一种更简单,更整齐的方法。如果您将搜索窗口小部件用作工具栏(https://developer.android.com/guide/topics/search/search-dialog#UsingSearchWidget)中的操作视图,则可能需要使SearchView失去焦点并在用户触摸屏幕上的其他任何地方时隐藏键盘。

除了在SearhView之外的层次结构中的每个视图上迭代和设置触摸侦听器,您都可以简单地使用此solution,因为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);
}

就是这样!希望这对以后的读者有用:)

答案 3 :(得分:0)

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

    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);
}