搜索功能是Android常见的功能之一,在v7包就有一个控件SearchView,用来实现搜索功能,而在普通widget包中也有一个SearchView,两者用处一样,只不过在使用方式上有一点区别,同时widget包中的SearchView只能在3.0(API 11)版本以上使用,而v7包中的SearchView能兼容到2.1(API 7).
今天介绍的就是v7包中的SearchView.
使用前添加依赖:
compile 'com.android.support:appcompat-v7:25.3.1'
一、单独使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.SearchView
android:id="@+id/searview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:iconifiedByDefault="false"
app:queryHint="请输入搜索内容" />
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private SearchView mSearchView;
private ListView mListView;
private ArrayAdapter mAdapter;
private String [] data = {"Java","kotlin","C","C++","C#","Python","PHP","JavaScript"};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listview);
mAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, data);
mListView.setAdapter(mAdapter);
mListView.setTextFilterEnabled(true);
mSearchView = (SearchView) findViewById(R.id.searview);
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
mAdapter.getFilter().filter(newText);
return false;
}
});
}
}
这里为了书写简便就没有搭配RecyclerView了,而是搭配ListView使用,为SearchView设置了一个监听,当搜索框内容变化时,ListView动态过滤内容.
二、SearchView常用属性、方法
1、搜索图标
默认样式:搜索框默认是关闭的,左侧搜索图标在搜索框中,可以通过右侧叉叉关闭搜索框
默认样式
(1) 方法SearchView.setIconified(false);
搜索框默认是开启的,左侧搜索图标在搜索框中,可以通过右侧叉叉关闭搜索框
setIconified(false)
(2) 方法SearchView.setIconifiedByDefault(false);
或者属性app:iconifiedByDefault="false"
搜索框默认是开启的,左侧搜索图标在搜索框外
右侧一开始没有叉叉,有输入内容后出现叉叉,叉叉只能清除搜索框内容,无法关闭搜索框
app:iconifiedByDefault="false"
(3) 修改搜索图标
app:searchIcon=""
2、搜索框中提示内容
app:queryHint=" "
或者方法:SearchView.setQueryHint(...)
3、关闭图标(就是那个叉叉)
app:closeIcon=" "
4、搜索框展开时显示提交按钮
SearchView.setSubmitButtonEnabled(true);
5、事件监听
//搜索图标按钮的点击事件
mSearchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "打开搜索框", Toast.LENGTH_SHORT).show();
}
});
//搜索框内容变化监听
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {//点击提交按钮时
Toast.makeText(MainActivity.this, "Submit---提交", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {//搜索框内容变化时
if (!TextUtils.isEmpty(newText)) {
// mListView.setFilterText(newText);
mAdapter.getFilter().filter(newText);
} else {
mListView.clearTextFilter();
}
return true;
}
});
//搜索框展开时点击叉叉按钮关闭搜索框的点击事件
mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
Toast.makeText(MainActivity.this, "关闭搜索框", Toast.LENGTH_SHORT).show();
return false;
}
});
三、搭配Toolbar使用
SearchView搭配Toolbar也是非常常见的一种使用方式.
1、方式一
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:titleTextColor="@android:color/white" />
</LinearLayout>
菜单文件
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_searchview"
android:title="没什么鸟用的title"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" />
</menu>
Activity中
public class MainActivity extends AppCompatActivity {
private SearchView mSearchView;
private Toolbar mToolbar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
}
/**
* 重写此方法显示Menu Item
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu);
MenuItem menuItem = menu.findItem(R.id.item_searchview);
//通过MenuItem得到SearchView
mSearchView = (SearchView) MenuItemCompat.getActionView(menuItem);
return true;
}
}
1)这个menu item跟普通item的差别在于使用了app:actionViewClass属性,app:actionViewClass="android.support.v7.widget.SearchView"表明使用了v7包下的SearchView.
2)注意:这里我们使用的是v7包下的SearchView,所以不要写成android:actionViewClass="android.widget.SearchView".
3)这里的title并没有什么鸟用,因为使用搜索功能时我们一般不会把它放进溢出菜单中,但是不写是会报错的.
4)如果在android:showAsAction属性中加上collapseActionView属性,那么MenuItem的icon属性必须就要加上了,不然会显示title文字的.
同时点开后的样式也不一样了,左侧会出现一个箭头,点击箭头退出搜索模式.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_searchview"
android:title="没什么鸟用的title"
app:actionViewClass="android.support.v7.widget.SearchView"
android:icon="@drawable/icon_search"
app:showAsAction="always|collapseActionView" />
</menu>
2、方式二
因为Toolbar本身是一个ViewGroup,可以添加子View,所以我们可以把SearchView当做子View添加到Toolbar上.
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:titleTextColor="@android:color/white" >
<android.support.v7.widget.SearchView
android:id="@+id/searview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
app:queryHint="请输入搜索内容" />
</android.support.v7.widget.Toolbar>>
</LinearLayout>
Activity中
public class MainActivity extends AppCompatActivity {
private SearchView mSearchView;
private Toolbar mToolbar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mSearchView = (SearchView) mToolbar.findViewById(R.id.searview);
// do something
}
}
四、修改SearchView样式
观看SearchView源码可以发现,SearchView本身布局是通过xml布局文件来实现的.
public SearchView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
......
final LayoutInflater inflater = LayoutInflater.from(context);
final int layoutResId = a.getResourceId(
R.styleable.SearchView_layout, R.layout.abc_search_view); //☆ 看这里
inflater.inflate(layoutResId, this, true);
mSearchSrcTextView = (SearchAutoComplete) findViewById(R.id.search_src_text);
mSearchSrcTextView.setSearchView(this);
mSearchEditFrame = findViewById(R.id.search_edit_frame);
mSearchPlate = findViewById(R.id.search_plate);
mSubmitArea = findViewById(R.id.submit_area);
mSearchButton = (ImageView) findViewById(R.id.search_button);
mGoButton = (ImageView) findViewById(R.id.search_go_btn);
mCloseButton = (ImageView) findViewById(R.id.search_close_btn);
mVoiceButton = (ImageView) findViewById(R.id.search_voice_btn);
mCollapsedIcon = (ImageView) findViewById(R.id.search_mag_icon);
......
}
找到那个布局文件
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- This is actually used for the badge icon *or* the badge label (or neither) -->
<TextView
android:id="@+id/search_badge"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:layout_marginBottom="2dip"
android:drawablePadding="0dip"
android:textAppearance="?attr/textAppearanceMedium"
android:textColor="?attr/textColorPrimary"
android:visibility="gone" />
<ImageView
android:id="@+id/search_button"
style="?attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:focusable="true"
android:contentDescription="@string/searchview_description_search" />
<LinearLayout
android:id="@+id/search_edit_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginStart="8dip"
android:layout_marginEnd="8dip"
android:orientation="horizontal"
android:layoutDirection="locale">
<ImageView
android:id="@+id/search_mag_icon"
android:layout_width="@dimen/dropdownitem_icon_width"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:layout_marginStart="@dimen/dropdownitem_text_padding_left"
android:layout_gravity="center_vertical"
android:visibility="gone" />
<!-- Inner layout contains the app icon, button(s) and EditText -->
<LinearLayout
android:id="@+id/search_plate"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<view class="android.widget.SearchView$SearchAutoComplete"
android:id="@+id/search_src_text"
android:layout_height="36dip"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:paddingStart="@dimen/dropdownitem_text_padding_left"
android:paddingEnd="@dimen/dropdownitem_text_padding_right"
android:singleLine="true"
android:ellipsize="end"
android:background="@null"
android:inputType="text|textAutoComplete|textNoSuggestions"
android:imeOptions="actionSearch"
android:dropDownHeight="wrap_content"
android:dropDownAnchor="@id/search_edit_frame"
android:dropDownVerticalOffset="0dip"
android:dropDownHorizontalOffset="0dip" />
<ImageView
android:id="@+id/search_close_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="8dip"
android:paddingEnd="8dip"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:focusable="true"
android:contentDescription="@string/searchview_description_clear" />
</LinearLayout>
<LinearLayout
android:id="@+id/submit_area"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:id="@+id/search_go_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:paddingStart="16dip"
android:paddingEnd="16dip"
android:background="?attr/selectableItemBackgroundBorderless"
android:visibility="gone"
android:focusable="true"
android:contentDescription="@string/searchview_description_submit" />
<ImageView
android:id="@+id/search_voice_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:paddingStart="16dip"
android:paddingEnd="16dip"
android:background="?attr/selectableItemBackgroundBorderless"
android:visibility="gone"
android:focusable="true"
android:contentDescription="@string/searchview_description_voice" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
ok,既然是一个布局文件,而且每一个组件都有id,那么直接通过SearchView.findViewById()找到你想要改变的组件,然后设置你想要的样式不就可以了.
方式1 :代码修改
//搜索框
SearchView.SearchAutoComplete tv = (SearchView.SearchAutoComplete) mSearchView.findViewById(R.id.search_src_text);
tv.setTextColor(Color.WHITE);
tv.setHintTextColor(Color.WHITE);
//搜索按钮
ImageView ivSearch1 = (ImageView) mSearchView.findViewById(R.id.search_button);
ivSearch1.setImageResource(R.drawable.a);
//关闭按钮
ImageView ivClose = (ImageView) mSearchView.findViewById(R.id.search_close_btn);
ivClose.setImageResource(R.drawable.b);
更多的样式你可以自己去设置,这里就不一一设置了.
方式2:style修改
原生的SearchView样式像下面这样:
<style name="Base.Widget.AppCompat.SearchView" parent="android:Widget">
<item name="layout">@layout/abc_search_view</item>
<item name="queryBackground">@drawable/abc_textfield_search_material</item>
<item name="submitBackground">@drawable/abc_textfield_search_material</item>
<item name="closeIcon">@drawable/abc_ic_clear_material</item>
<item name="searchIcon">@drawable/abc_ic_search_api_material</item>
<item name="searchHintIcon">@drawable/abc_ic_search_api_material</item>
<item name="goIcon">@drawable/abc_ic_go_search_api_material</item>
<item name="voiceIcon">@drawable/abc_ic_voice_search_api_material</item>
<item name="commitIcon">@drawable/abc_ic_commit_search_api_mtrl_alpha</item>
<item name="suggestionRowLayout">@layout/abc_search_dropdown_item_icons_2line</item>
</style>
我们可以在上面做一些修改:
<style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView">
<item name="android:layout">@layout/abc_search_view</item>
<item name="queryBackground">@drawable/abc_textfield_search_material</item>
<item name="submitBackground">@drawable/abc_textfield_search_material</item>
<item name="closeIcon">@drawable/abc_ic_clear_material</item>
<item name="searchIcon">@drawable/abc_ic_search_api_material</item>
<item name="goIcon">@drawable/abc_ic_go_search_api_material</item>
<item name="voiceIcon">@drawable/abc_ic_voice_search_api_material</item>
<item name="commitIcon">@drawable/abc_ic_commit_search_api_mtrl_alpha</item>
<item name="suggestionRowLayout">@layout/abc_search_dropdown_item_icons_2line</item>
<item name="defaultQueryHint">请输入搜索内容</item>
<item name="searchHintIcon">@drawable/icon_search</item>
</style>
然后引用该样式即可,想要全局修改直接放在主题style中:
<item name="searchViewStyle">@style/MySearchViewStyle</item>
只想修改某一个的话给那个SearchView引用即可
style="@style/MySearchViewStyle"
网友评论