自动折叠ActionBar SearchView在软键盘上关闭


79

我目前正在使用ActionBar菜单项在操作栏中显示SearchView。展开搜索菜单项后,将显示我想要的软键盘。现在,当用户按下后退按钮以关闭软键盘时,我也想在操作栏中折叠SearchView。

我已经尝试在MenuItem和ActionView上实现以下侦听器OnKeyListener和OnFocusChangeListener。我也尝试在Activity中使用OnBackPressed()。当使用后退按钮关闭软键盘时,以上方法均无法检测。

有任何想法吗?

我已经实现了OnActionExpandListener,以知道何时可以看到SearchView。


这里是一个非常受欢迎的答案stackoverflow.com/questions/1109022/...
jmishra

2
这无济于事,他需要拦截键盘上的后退键
dor506'3

@acrespo什么答案?您对一个问题发表评论...
令人难以置信的

Answers:


100

我将扩展@ user1258568的答案。这对我有用。请注意,当焦点丢失时,它将清除您的查询。

final MenuItem searchMenuItem = optionsMenu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();

searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean queryTextFocused) {
        if(!queryTextFocused) {
            searchMenuItem.collapseActionView();
            searchView.setQuery("", false);
        }
    }
});

1
完美运作。如果在代码中添加searchView,则可能需要使用menu.getItem(yourSearchViewItemPosition)
GeeF,

@AlexBonel怎么回事?我知道S3和S4都有白痴的硬件按钮,但是我不清楚这将如何影响此代码段。可能是因为ActionBar菜单被隐藏并且searchMenuItem的行为不同。我手上有一个S4,我必须测试一下。
乔恩·威利斯

@JonWillis如果对您来说并不困难,请您分享一下S4上这种行为的经验吗?
Alex Bonel 2013年

4
很好,经过数小时的研究和实现,我找到了您的答案:) ...我想的第一件事是使用焦点监听器,但我使用setOnFocusChangeListener()而不是setOnQueryTextFocusChangeListener()。使用您的方法,一切正常。谢谢。
Ionut Negru 2014年

2
@IonutNegru不客气!有时会喜欢Android SDK。我想看到他们以理智,现代的方式重写它,并放弃旧的支持,但这将永远不会发生。
乔恩·威利斯

37

我找到了更好的解决方案。

searchView.setOnQueryTextFocusChangeListener(). 

OnQueryTextFocusChangeListener显示或隐藏键盘的时候被调用。显示键盘时首先被调用,并且搜索视图将具有焦点。keyboard隐藏时再次被调用,搜索视图将失去焦点,close search view然后可以使用

menuItem.collapseActionView().

5
这是误导。该OnQueryTextFocusChangeListener显示或隐藏键盘时不会被调用。仅当searchView焦点对准或焦点对准时才调用它。因此,SearchView第一次将焦点对准时,将OnQueryTextFocusChangeListener调用并同时显示键盘。现在,如果按下后退按钮,键盘将被隐藏,但OnQueryTextFocusChangeListener不会被调用。再次按下返回按钮时,将searchView折叠并被OnQueryTextFocusChangeListener调用。
faizal

11

像这样重写onBackPressed:

@Override
    public void onBackPressed() {
        if (searchView.isShown()){
            searchView.onActionViewCollapsed();  //collapse your ActionView
            searchView.setQuery("",false);       //clears your query without submit
            isClosed = true;                     //needed to handle closed by back
        } else{
            super.onBackPressed();
        }
    }

并且您的onCreateOptionsMenu会像这样使mSearchView膨胀:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu_search, menu);
        mSearchView = (SearchView) menu.findItem(R.id.menu_action_search).getActionView();
        mSearchView.setOnQueryTextListener(this);
        mSearchView.setOnSearchClickListener(this);
        mSearchView.setOnCloseListener(this);
        isClosed = true;
        return true;
    }

你有没有像这样实现以下内容:

public class myActivity extends FragmentActivity implements
    SearchView.OnQueryTextListener, View.OnClickListener, SearchView.OnCloseListener {

您还需要:

@Override
public void onClick(View view) {
    isClosed = false;
}

@Override
public boolean onClose() {
    isClosed = true;
    return false;
}

您将需要使“ mSearchView”和“ isClosed”均为活动的全局变量。


3
我认为那行不通;以我的经验,如果键盘向上,则不会调用onBackPressed方法;它只是关闭了键盘,您需要再次按下以使其调用该方法。这是在2.3; 我还没有尝试过3.x和4.0,但是我怀疑那里也一样。
凯夫拉尔2012年

@凯夫拉尔,我认为你可能是正确的。我将再次进行测试,并确保没有办法。看来我的解决方案确实与他们想要的略有不同。据我所知,在显示软键盘时,我认为没有办法处理任何背部。确定关闭键盘后,我的解决方案即可处理。将在不同的SDK上进行测试。
2012年

1
我曾尝试使用以下方法折叠搜索:searchMenuItem.collapseActionView(); 但事实证明,searchView.onActionViewCollapsed(); 为我做了把戏-谢谢!
bkurzius

我认为您不应该直接调用...函数。这些功能不能直接从您的代码中调用...
user457015

如何在API级11使用collapseActionView()
麻石V

3

乔恩·威利斯的答案很有效。这是对他的回答的改进。

首先,创建一个实现的新类View.OnFocusChangeListener

public class SearchViewFocusListener implements View.OnFocusChangeListener {

    private final MenuItem mMenuItem;

    public SearchViewFocusListener(MenuItem menuItem) {
        mMenuItem = menuItem;
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            mMenuItem.collapseActionView();
            if (v instanceof SearchView) {
                ((SearchView) v).setQuery("", false);
            }
        }
    }

}

接下来,在您的上设置监听器SearchView

searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));

效果很好,但是如何从搜索图标中清除焦点?FocusChangeListener捕获按下设备上的“后退”按钮,然后关闭软键盘并关闭SearchView,然后按照我的意愿出现搜索图标。但是,搜索图标突出显示(具有焦点),我希望它没有焦点。我尝试了几种清除方法,但是没有运气。有任何想法吗?
AJW

2

您只需要在菜单布局中放置“ collapseActionView”属性

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_item_search"
        android:title="@string/search"
        android:iconifiedByDefault="true"
        android:icon="@drawable/ic_action_search" 
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView"/> <--this one
</menu>

这将为您提供单独寻找的功能。不要忘记在发送查询后在SearchView上调用方法“ clearFocus”来关闭键盘。


1

这就是我使键盘消失的方法。您可以尝试看看这是否适合您。我将设置searchView为不可见,然后再次设置为可见。

    //set query change listener
     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
        @Override
        public boolean onQueryTextChange(String newText) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onQueryTextSubmit(String query) {
            /**
             * hides and then unhides search tab to make sure keyboard disappears when query is submitted
             */
                  searchView.setVisibility(View.INVISIBLE);
                  searchView.setVisibility(View.VISIBLE);
            return false;
        }

     });

同样为我工作,但是您必须添加getActivity()。supportInvalidateOptionsMenu(); 恢复操作栏
almisoft

1

可以这样实现:

   private void setupSearchView(Menu menu) {
        final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) searchMenuItem.getActionView();

        [...]

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                searchMenuItem.collapseActionView();
                return false;
            }
            @Override
            public boolean onQueryTextChange(String newText) {
                return true;
            }
        });
    }

基于setOnQueryTextFocusChangeListener()的解决方案对我不起作用,因为该事件未启动-提交时searchView不会失去焦点,可能是因为我在包含Search View的同一活动中执行了搜索。

无论如何,我认为使用OnQueryTextListener更正确,因为它描述了更精确地提交文本的事件。


0
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.home_screen, menu);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        final MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
        final SearchView searchView = (SearchView) searchMenuItem
                .getActionView();
        searchView.setIconifiedByDefault(false);
        if (searchManager != null && searchView != null) {
            searchView.setSearchableInfo(searchManager
                    .getSearchableInfo(getComponentName()));

            searchView
                    .setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {

                        @Override
                        public void onFocusChange(View v, boolean hasFocus) {

                            if (!hasFocus) {
                                if (searchMenuItem != null) {
                                    searchMenuItem.collapseActionView();
                                }// end if
                                if (searchView != null) {
                                    searchView.setQuery("", false);

                                }// end if
                            }// end if

                        }
                    });

            searchView
                    .setOnQueryTextListener(new SearchView.OnQueryTextListener() {

                        @Override
                        public boolean onQueryTextSubmit(String query) {
                            /**
                             * hides and then unhides search tab to make sure
                             * keyboard disappears when query is submitted
                             */
                            if (searchView != null) {
                                searchView.setVisibility(View.INVISIBLE);
                                searchView.setVisibility(View.VISIBLE);

                            }
                            return false;
                        }

                        @Override
                        public boolean onQueryTextChange(String newText) {
                            // TODO Auto-generated method stub
                            return false;
                        }
                    });

        }

        return super.onCreateOptionsMenu(menu);
    }

0

如果要在用户单击键盘上的搜索图标时折叠键盘,可以通过简单的方法来实现

inside onquerytextsubmitted {

searchView.clearfocus()

}


0

您需要调用setIconified两次。

要实际折叠您的搜索视图并关闭键盘。
第一次呼叫时,用第二个呼叫键盘清除搜索视图的文本,然后关闭搜索视图。


0

由于某种原因,它menuItem.collapseActionView()没有用,所以我searchView.setIconified(true)改用了。

这给出了以下结果作为代码示例。

final MenuItem searchItem = (MenuItem) menu.findItem(R.id.menu_item_search);
final SearchView searchView = (SearchView) searchItem.getActionView();

searchView.setOnQueryTextFocusChangeListener(new SearchView.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            searchView.setIconified(true);
        }
    }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.