SearchView小巧的搜索控件
应用一个重要的功能是提供搜索,可以自己结合EditText和Button完成一个输入搜索的功能模块。但是不用那么麻烦,Android已经为我们集成好了一个功能强大的空间SearchView,通常和ToolBar一起使用,放在Menu菜单中展示。

1、Menu中定义SearchView
从设计上来讲,最好一直显示在Toolbar上,showAsAction属性设定为"always"。另外一个将item设置为SearchView,需要设置属性app:actionViewClass="****.SearchView",表明这个item是SearchView
<item
android:id="@+id/search"
android:orderInCategory="1"
android:title="搜索"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always" />2、初始化SearchView
一般定义一个全局的SearchView成员变量,方便操作。在menu创建初始化后,去初始化这个全局变量。
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_overflow, menu);
MenuItem menuItem = menu.findItem(R.id.menu_refresh);
mSearchView = (SearchView) (menuItem.getActionView());
... ...
}3、SearchView的属性
①setIconifiedByDefault(boolean):设置SearchView是否默认以搜索图标的形式显示。ByDefault表示清空文字时的默认状态。
false表示SearchView直接展开。注意左侧有搜索图标
mSearchView.setIconifiedByDefault(false);
为true默认折叠成一个搜索图标
mSearchView.setIconifiedByDefault(true);
②setIconified(boolean):设置初始时的状态是否展开或者收起,注意和ByDefault的区别,可以点击"X"号将其收起,也可以点击图标将其展开。
false表示SearchView直接展开。注意左侧没有搜索图标
mSearchView.setIconified(false);
③onActionViewExpanded()
设置SearchView直接展开显示,左侧没有搜索图标,也不能关闭搜索框。

④setQueryHint(String ):设置SearchView的提示词。SearchView本身集成了EditTextView,后面也可以借助获取到EditText设置setHint(String)。
mSearchView.setQueryHint("SearchView提示hint");
4、SearchView输入监听
前面铺垫那么多,最重要的是获取到输入的keyword进行搜索。一种是输入完之后点击搜索,才进行搜索。另一种是随着输入字符的变化动态搜索。
幸亏SearchView给我们提供了监听接口SearchView.OnQueryTextListener,可以方便的实现这两种功能。
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
doSearch(newText);
return true;
}
});通过监听输入字符去进行搜索逻辑的处理。
5、SearchView输入提示
输入的时候如果能够给用户进行实时的提示匹配,极大的提高APP使用体验。这个提示数据源可以是本地的,也可以动态根据输入从服务端获取显示给用户提示。
首先,获取到SearchView内部封装的SearchView.SearchAutoComplete对象。从名字就可以知道有自动补全功能。通过源码可以看到这个内部封装的类层层继承自EditText:
class SearchAutoComplete extends AppCompatAutoCompleteTextView
↓
class AppCompatAutoCompleteTextView extends AutoCompleteTextView implements TintableBackgroundView
↓
class AutoCompleteTextView extends EditText implements Filter.FilterListener借助SearchView对象拿到内部的SearchView.SearchAutoComplete对象,这个R.id.search_src_text是内部布局写死的不用管,直接使用。
mSearchText = mSearchView.findViewById(R.id.search_src_text);拿到这个对象,就可以设置一些属性,也就是我们真正的输入框:
//设置输入框内输入文字的颜色
mSearchText.setTextColor(Color.BLACK);
//设置提示hint的颜色
mSearchText.setHintTextColor(Color.BLUE);
//和前面通过SearchView一样,设置输入提示hint
mSearchText.setHint("搜索")
//设置输入多少个字符才有提示,默认为2个字符。设置成1个体验较好。
mSearchText.setThreshold(1);其次,创建适配器,数据集不能直接设置给SearchView.SearchAutoComplete,先将数据集合借助Adapte设置给SearchView.SearchAutoComplete。
ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, R.layout.search_list_auto, hintDataLists);
mSearchText.setAdapter(adapter);这样在输入的时候就可以看到输入框底部实时的有提示弹出。

当然还可以把功能做的更好,点击弹出的提示,直接将提示选项设置给SearchView,进行搜索。给SearchView.SearchAutoComplete对象添加点击事件即可:
mSearchText.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mSearchText.setText(((TextView) view).getText());
}
});
