今天公司暖气来了,意味着又到了年末。我们日夜重复着昨天的生活像白开水一样的活着,忙碌着却无成绩的挣扎着。没关系,有些人还是很快乐因为它们从中得到了充实,自乐其中。可是我们不要忘了这个世界上只有活的有意义才是最大的幸福。通过博客来记录生活与技术,只有把一些东西写下来,才能让我看得更明白,才能不断发现迷失的自己。今天我们就来讲一下Android开发中的寻找(SearchView)。首先,我们看一下今天要实现的SearchView的展示效果:
上一节我们已经讲了SearchView是显示在ToolBar上的一个搜、索控件,这节我们就详细讲解下它的用法,为了故事的完整性我们还是从ToolBar开始。
一、ToolBar的展示与菜单(包括SearchView)
1. activity_main.xml(后面MainActivity的布局)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/Toolbar.MyStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:title="我的Tool"
app:titleTextColor="@color/colorWhite"
app:navigationIcon="@mipmap/gongzhong_fanhui"
app:titleTextAppearance="@style/Toolbar.TitleText"
>
</android.support.v7.widget.Toolbar>
</LinearLayout>
activity_main.xml里声明了一个ToolBar,android:background背景色为主题颜色,app:title标题为“我的Tool”,app:titleTextColor标题颜色为白色,app:navigationIcon返回箭头,app:titleTextAppearance="@style/Toolbar.TitleText"标题的字体样式在values-styles样式文件里定义如下(字体大小为15sp):
<!--Toolbar标题文字大小-->
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">15sp</item>
</style>
style="@style/Toolbar.MyStyle"整个ToolBar的样式在values-styles样式文件里定义如下:
<style name="Toolbar.MyStyle" parent="Base.Widget.AppCompat.Toolbar">
<item name="contentInsetStart">0dp</item>
<item name="contentInsetStartWithNavigation">0dp</item>
</style>
其中 <item name="contentInsetStart">0dp</item> 与<item name="contentInsetStartWithNavigation">0dp</item>的作用是让标题“我的ToolBar”离 返回箭头更贴近一些,因为默认标题与返回箭头间的空隙太大。截至目前整个styles.xml文件内容如下:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<!--标题与NavigationIcon的距离-->
<style name="Toolbar.MyStyle" parent="Base.Widget.AppCompat.Toolbar">
<item name="contentInsetStart">0dp</item>
<item name="contentInsetStartWithNavigation">0dp</item>
</style>
<!--Toolbar标题文字大小-->
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textSize">15sp</item>
</style>
</resources>
2. 菜单定义menu---main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.ricky.materialdesign.toolbar.MainActivity"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_search"
android:orderInCategory="100"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"
android:title="查找"/>
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
app:showAsAction="never"
android:title="设置"/>
<item
android:id="@+id/action_share"
android:orderInCategory="100"
app:showAsAction="always"
android:title="分享"
android:icon="@android:drawable/ic_menu_share"/>
<item
android:id="@+id/action_edit"
android:orderInCategory="100"
app:showAsAction="ifRoom"
android:title="编辑"
android:icon="@android:drawable/ic_menu_edit"/>
</menu>
main.xml里定义了4个菜单项,第一个菜单项就是我们定义的SearchView, app:showAsAction="always"表示这个搜索控件总会显示在ToolBar表面,第二个菜单项是设置菜单 app:showAsAction="never"意味着它将隐藏在右上角三个...的菜单里。第三个是分享菜单项,它与SearchView一样也会显示在ToolBar表面。第四个菜单项—编辑菜单,app:showAsAction="ifRoom"属性表示如果ToolBar表面还有空间的话那么它也将显示在ToolBar表面。
3. MainActivity.java
加载activity_main.xml与menu--main.xml来显示ToolBar和它附带的菜单项。
package com.example.administrator.toolbarstudy;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnCloseListener;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
SearchView.SearchAutoComplete mSearchAutoComplete;
SearchView mSearchView;
MyAdapter adapter;
String TAG = "MainActivity";
ListView lvAutoText;
List<String> namesCollection = new ArrayList<>();
List<String> names = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(true);
//返回键
toolbar.setNavigationOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
clickBack();
}
});
}
/**
* 点击返回(包括手机物理按键)
*/
public void clickBack()
{
if (mSearchAutoComplete.isShown()) {
try {
//折叠搜索框
mSearchAutoComplete.setText("");
Method method = mSearchView.getClass().getDeclaredMethod("onCloseClicked");
method.setAccessible(true);
method.invoke(mSearchView);
} catch (Exception e) {
e.printStackTrace();
}
} else {
finish();
}
return;
}
/**
* 让菜单同时显示图标和文字
* @param featureId
* @param menu
* @return
*/
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (menu != null) {
if (menu.getClass().getSimpleName().equalsIgnoreCase("MenuBuilder")) {
try {
Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
method.setAccessible(true);
method.invoke(menu, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return super.onMenuOpened(featureId, menu);
}
/**
* 根据menu--main.xml加载菜单
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(item);
//通过id得到搜索框控件
mSearchAutoComplete = (SearchView.SearchAutoComplete) mSearchView.findViewById(R.id.search_src_text);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Toast.makeText(MainActivity.this,"您点击了设置",Toast.LENGTH_SHORT).show();
return true;
}
else if(id == R.id.action_share)
{
Toast.makeText(MainActivity.this,"您点击了分享",Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* 按系统返回键与按标题栏上的返回产生相同的效果
* @param keyCode
* @param event
* @return
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK)
{
clickBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
代码分析
3.1 折叠搜索控件(SearchView)
在上述代码里我们定义了返回键的响应处理
//返回键
toolbar.setNavigationOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
clickBack();
}
});
clickBack函数实现了一个功能,就是当搜索框展开显示的时候,折叠SearchView(搜索框),如果SearchView本来就是折叠的则点返回键直接关闭当前页面。同时,我们在Activity的onKeyDown里也调用的clickBack函数。其中mSearchAutoComplete.就是搜索文本框,它是一个自动完成文本框,mSearchView就是SearchView控件实例,它们都在onCreateOptionsMenu函数里创建。
3.2 加载SearchView
onCreateOptionsMenu函数从menu--main.xml里加载出各菜单,并从中得到了mSearchView 与mSearchASutoComplete,这两个控件实例分别是SearchView控件与 SearchView控件中的搜索文本框,这两个变量在3.1中的clickBack函数中有使用。
3.3 菜单项的点击事件
onOptionsItemSelected函数里处理了菜单的点击事件。
3.4 onMenuOpened
让菜单项同时显示图标与文本,例如下图中的“编辑”菜单项:
4. 界面效果
4.1 截止目前,运行效果如下:
点击搜索图标展开SearchView控件,输入文本后点右边的叉号删除文本,当SearchView展开的时候点返回箭头则折叠SearchView搜索文本框,当SearchView已经折叠的时候,然后继续按返回键则关闭当前页面(这种情况以下动画中没有演示)。
4.2 改进UI
我们从上述运行效果图中可以看出:
“搜索图标”、“搜索文字”、“X号”、“三个点点”的颜色都是黑色,能不能让它们变成白色。答案是可以的!为AppTheme添加一个配置android:textColorSecondary将其设置为白色可以改变菜单项图标的颜色。
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!--设置menu中item的图标颜色-->
<item name="android:textColorSecondary">@color/colorWhite</item>-->
</style>
同时在MainActivity.java代码中onCreateOptionsMenu函数里添加代码:
int colorWhite = this.getResources().getColor(R.color.colorWhite);
mSearchAutoComplete.setTextColor(colorWhite);
其中mSearchAutoComplete就是那个搜索文本框。
这样再运行效果如下:
这下界面颜色一致了都是白色的了,漂亮多了。这只是个UI,接下来我们研究一下与SearchView相关的事件处理函数以及结合ListView实现 “搜索自动提示” 功能。
二、SearchView相关代码
1. SearchView相关代码:
/**
* 根据menu--main.xml加载菜单
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(item);
//设置最大宽度mSearchView.setMaxWidth
//通过id得到搜索文本框控件
mSearchAutoComplete = (SearchView.SearchAutoComplete) mSearchView.findViewById(R.id.search_src_text);
int color = this.getResources().getColor(R.color.colorWhite);
mSearchAutoComplete.setTextColor(color);
/*------------------ SearchView有三种默认展开搜索框的设置方式,区别如下: ------------------*/
//1.设置搜索框直接展开显示。左侧有放大镜(在搜索框外) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
//searchView.setIconifiedByDefault(false);
//2.设置搜索框直接展开显示。左侧有放大镜(在搜索框中) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
mSearchView.onActionViewExpanded();
//3.false设置搜索框直接展开显示,true缩减为一个搜索图标。左侧有放大镜(在搜索框中) 右侧有叉叉 可以关闭搜索框
mSearchView.setIconified(true);
//SearchView用到了一个布局,在V7compat里面找到abc_search_view.xml,在里面可以找到SearchView各组成部分的资源ID
//设置"提交搜索"按钮的图标,就是那个">"右箭头提交按钮
//ImageView icon = (ImageView) mSearchView.findViewById(R.id.search_go_btn);
//icon.setImageResource(R.mipmap.voice_search);
//设置搜索框文本的hint,与mSearchAutoComplete.setHint功能一样
mSearchView.setQueryHint("搜索本地歌曲by code");
//设置搜索文本框的字体
mSearchAutoComplete.setHintTextColor(getResources().getColor(android.R.color.darker_gray));
mSearchAutoComplete.setTextColor(getResources().getColor(android.R.color.background_light));
mSearchAutoComplete.setTextSize(14);
//修改搜索框控件间的间隔(这样只是为了在细节上更加接近网易云音乐的搜索框)
LinearLayout search_edit_frame = (LinearLayout) mSearchView.findViewById(R.id.search_edit_frame);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) search_edit_frame.getLayoutParams();
params.leftMargin = 0;
params.rightMargin = 0;
search_edit_frame.setLayoutParams(params);
//设置提交按钮是否可用(可见)
mSearchView.setSubmitButtonEnabled(true);
//searchView.setSuggestionsAdapter(adapter)
//监听mSearchAutoComplete文本框焦点改变,例如点返回键后SearchView折叠mSearchAutoComplete失去了焦点时执行
mSearchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
Log.i(TAG,"onFocusChange");
}
});
//searchView折叠监听,当前项目中点击返回键时执行
mSearchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
Log.i(TAG,"OnCloseListener");
return false;
}
});
////搜索图标按钮(打开搜索框的按钮)的点击事件
mSearchView.setOnSearchClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "点击了搜索图标按钮", Toast.LENGTH_SHORT).show();
}
});
//监听文本变化,调用查询
mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
//X右边的"搜索提交"按钮
@Override
public boolean onQueryTextSubmit(String text) {
Toast.makeText(MainActivity.this, "点击了提交按钮:"+text, Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onQueryTextChange(String text) {
// 文本改变的时候回调
Log.i(TAG,"文本变化~~~~~"+text);
return false;
}
});
return true;
}
注释还是比较全的。在 这里我们主要看一下setOnQueryTextListener,它包含2个回调函数onQueryTextSubmit与onQueryTextChange,其中onQueryTextChange检测文本变化,例如当你输入字母a时就会调用这个函数,这个正好可以用来实现那种边输入边搜索的效果。
2. SearchView结合Listviews实现自动提示
我们可以结合Listview来实现边搜索边提示的功能。例如输入a,则请求服务器,服务器会返回abc, aaa,acd ...等包含a的搜索提示列表。在这里我们不请求服务器,为了演示方便我们把“搜索提示文本的集合”放在本地,如一个字符串数组:
List<String> namesCollection = new ArrayList<>();
namesCollection.add("abcd");
namesCollection.add("adc");
namesCollection.add("bbc");
namesCollection.add("bac");
namesCollection.add("cab");
namesCollection.add("ccb")
到时候我们在搜索文本框里输入a,ListView将显示abcd, adc, bac,cab. 输入d将显示adc. 那我们在何处去从集合里筛选呢,答案是从onQueryTextChange里监听输入文本的变化,每输入一个字符会去从集合中筛选出与输入匹配的字符串,最终显示在Listview里。好了原理分析完了,我们看具体如何实现:
2.1 布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/Toolbar.MyStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:title="我的Tool"
app:titleTextColor="@color/colorWhite"
app:navigationIcon="@mipmap/gongzhong_fanhui"
app:titleTextAppearance="@style/Toolbar.TitleText"
>
</android.support.v7.widget.Toolbar>
<ListView
android:layout_gravity="center_horizontal"
android:divider="@color/colorPrimary"
android:dividerHeight="0.3dp"
android:id="@+id/lvAutoText"
android:layout_width="300dp"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
2.2 MainActivity.java代码
package com.example.administrator.toolbarstudy;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnCloseListener;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
SearchView.SearchAutoComplete mSearchAutoComplete;
SearchView mSearchView;
MyAdapter adapter;
String TAG = "MainActivity";
ListView lvAutoText;
List<String> namesCollection = new ArrayList<>();
List<String> filterNames = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(true);
//返回键
toolbar.setNavigationOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
clickBack();
}
});
lvAutoText = this.findViewById(R.id.lvAutoText);
namesCollection.add("abcd");
namesCollection.add("adc");
namesCollection.add("bbc");
namesCollection.add("bac");
namesCollection.add("cab");
namesCollection.add("ccb");
filterNames.addAll(namesCollection);
adapter = new MyAdapter(filterNames,this);
lvAutoText.setAdapter(adapter);
}
/**
* 点击返回(包括手机物理按键)
*/
public void clickBack()
{
if (mSearchAutoComplete.isShown()) {
try {
//如果搜索框中有文字,则会先清空文字,但网易云音乐是在点击返回键时直接关闭搜索框
mSearchAutoComplete.setText("");
Method method = mSearchView.getClass().getDeclaredMethod("onCloseClicked");
method.setAccessible(true);
method.invoke(mSearchView);
} catch (Exception e) {
e.printStackTrace();
}
} else {
finish();
}
return;
}
/**
* 让菜单同时显示图标和文字
* @param featureId
* @param menu
* @return
*/
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (menu != null) {
if (menu.getClass().getSimpleName().equalsIgnoreCase("MenuBuilder")) {
try {
Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
method.setAccessible(true);
method.invoke(menu, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return super.onMenuOpened(featureId, menu);
}
/**
* 根据menu--main.xml加载菜单
* @param menu
* @return
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(item);
//设置最大宽度mSearchView.setMaxWidth
//通过id得到搜索框控件
mSearchAutoComplete = (SearchView.SearchAutoComplete) mSearchView.findViewById(R.id.search_src_text);
int color = this.getResources().getColor(R.color.colorWhite);
mSearchAutoComplete.setTextColor(color);
/*------------------ SearchView有三种默认展开搜索框的设置方式,区别如下: ------------------*/
//1.设置搜索框直接展开显示。左侧有放大镜(在搜索框外) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
//searchView.setIconifiedByDefault(false);
//2.设置搜索框直接展开显示。左侧有放大镜(在搜索框中) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
mSearchView.onActionViewExpanded();
//3.false设置搜索框直接展开显示,true缩减为一个搜索图标。左侧有放大镜(在搜索框中) 右侧有叉叉 可以关闭搜索框
mSearchView.setIconified(true);
//SearchView用到了一个布局compat里面找到abc_search_view.xml,该里面的控件的属性
//设置提交搜索按钮的图标
//ImageView icon = (ImageView) mSearchView.findViewById(R.id.search_go_btn);
//icon.setImageResource(R.mipmap.voice_search);
//设置搜索文本的hint,与mSearchAutoComplete.setHint功能一样
mSearchView.setQueryHint("搜索本地歌曲by code");
//设置搜索文本框的字体
mSearchAutoComplete.setHintTextColor(getResources().getColor(android.R.color.darker_gray));
mSearchAutoComplete.setTextColor(getResources().getColor(android.R.color.background_light));
mSearchAutoComplete.setTextSize(14);
//修改搜索框控件间的间隔(这样只是为了在细节上更加接近网易云音乐的搜索框)
LinearLayout search_edit_frame = (LinearLayout) mSearchView.findViewById(R.id.search_edit_frame);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) search_edit_frame.getLayoutParams();
params.leftMargin = 0;
params.rightMargin = 0;
search_edit_frame.setLayoutParams(params);
//设置提交按钮是否可用(可见)
mSearchView.setSubmitButtonEnabled(true);
//searchView.setSuggestionsAdapter(adapter)
//监听mSearchAutoComplete文本框焦点改变,例如点返回键后SearchView折叠mSearchAutoComplete失去了焦点时执行
mSearchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
Log.i(TAG,"onFocusChange");
}
});
//searchView折叠监听,当前项目中点击返回键时执行
mSearchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
Log.i(TAG,"OnCloseListener");
return false;
}
});
////搜索图标按钮(打开搜索框的按钮)的点击事件
mSearchView.setOnSearchClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "点击了搜索图标按钮", Toast.LENGTH_SHORT).show();
}
});
//监听文本变化,调用查询
mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
//X右边的"搜索提交"按钮
@Override
public boolean onQueryTextSubmit(String text) {
Toast.makeText(MainActivity.this, "点击了提交按钮:"+text, Toast.LENGTH_SHORT).show();
return false;
}
@Override
public boolean onQueryTextChange(String text) {
// 文本改变的时候回调
Log.i(TAG,"文本变化~~~~~"+text);
List<String> queryResult = QueryNames(namesCollection,text);
filterNames.clear();
if(queryResult != null && queryResult.size() > 0)
{
filterNames.addAll(queryResult);
}
setAdapter(adapter);
return false;
}
});
return true;
}
/**
* 从namesCollection集合中筛选与输入的文本想匹配的字符串
* @param namesCollection 提示文本(关键字)的集合,一般存在服务器数据库
* @param text 搜索框里输入的文本
* @return
*/
private List<String> QueryNames(List<String> namesCollection,String text) {
if(TextUtils.isEmpty(text))
{
return null;
}
List<String> temp = new ArrayList<>();
for(String name: namesCollection)
{
if(name.contains(text))
{
temp.add(name);
}
}
return temp;
}
/**
* 为ListView配置数据
* @param adapter
*/
public void setAdapter(ListAdapter adapter)
{
if(adapter == null)
{
adapter = new MyAdapter(filterNames,MainActivity.this);
lvAutoText.setAdapter(adapter);
}
else
{
if(adapter instanceof MyAdapter)
{
((MyAdapter)adapter).notifyDataSetChanged();
}
}
return;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
Toast.makeText(MainActivity.this,"您点击了设置",Toast.LENGTH_SHORT).show();
return true;
}
else if(id == R.id.action_share)
{
Toast.makeText(MainActivity.this,"您点击了分享",Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* 按系统返回键与按标题栏上的返回产生相同的效果
* @param keyCode
* @param event
* @return
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK)
{
clickBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
我们主要看以下代码片段:
public boolean onQueryTextChange(String text) {
// 文本改变的时候回调
Log.i(TAG,"文本变化~~~~~"+text);
List<String> queryResult = QueryNames(namesCollection,text);
filterNames.clear();
if(queryResult != null && queryResult.size() > 0)
{
filterNames.addAll(queryResult);
}
setAdapter(adapter);
return false;
}
/**
* 从namesCollection集合中筛选与输入的文本想匹配的字符串
* @param namesCollection 提示文本(关键字)的集合,一般存在服务器数据库
* @param text 搜索框里输入的文本
* @return
*/
private List<String> QueryNames(List<String> namesCollection,String text) {
if(TextUtils.isEmpty(text))
{
return null;
}
List<String> temp = new ArrayList<>();
for(String name: namesCollection)
{
if(name.contains(text))
{
temp.add(name);
}
}
return temp;
}
onQueryTextChange监听搜索文本框里的text变化,同时调用QueryNames函数从 集合中筛选出与text匹配的子集合,然后调用setAdapter展示子集合到ListView里。这样就模拟实现了自动提示文本,即一边输入一边提示“搜索关键字”的功能。就这么Easy!最终效果如图所示:
最后按照惯例给出源码下载地址:https://download.csdn.net/download/gaoxiaoweiandy/10789571