研究下searchview,使用searchview在中主布局中,不是在actionbar上,实现搜索提示功能
效果如下:
主布局文件activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.min.mysearchview.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="搜索" >
</TextView>
<SearchView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:queryHint="请输入关键字"
android:background="#fff"
android:iconifiedByDefault="false"
android:imeOptions="actionSearch"
android:inputType="textFilter" >
</SearchView>
<ListView
android:layout_marginTop="20dp"
android:id="@+id/lv"
android:divider="@null"
android:dividerHeight="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</ListView>
</LinearLayout>
很简单,一个textview来显示标题,一个searchview写入搜索字符串,一个listview来显示提示内容
要想将包含输入的字符的所有项都显示出来,而不仅仅匹配了首字母,需要自定义adapter并实现filerable接口:
package com.min.mysearchview;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
public class MySearchAdapter extends BaseAdapter implements Filterable {
private List<String> lists;
private LayoutInflater mLayoutInflater;
public MySearchAdapter(List<String> lists, Context context) {
this.lists = lists;
mLayoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return lists.size();
}
@Override
public Object getItem(int position) {
return lists.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mLayoutInflater.inflate(
R.layout.adapter_mysearchadapter, null);
holder.tv_adapter = (TextView) convertView
.findViewById(R.id.tv_adapter);
convertView.setTag(holder);
} else {
// 将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
holder = (ViewHolder) convertView.getTag();
}
holder.tv_adapter.setText((String) lists.get(position).toString());
return convertView;
}
// ViewHolder静态类
static class ViewHolder {
public TextView tv_adapter;
}
// 上面部分是对baseadapter的方法重写
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 继承Filterable接口就需要重写下面方法
@Override
// 返回自定义的filter
public Filter getFilter() {
return new ArrayFilter(lists);
}
// myFilter
public class ArrayFilter extends Filter {
private List<String> filterlists;
public ArrayFilter(List<String> filterlists) {
this.filterlists = filterlists;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 对字符串的匹配,这里采取了关键字匹配,不是字符串开头匹配
@Override
// 参数是输入框输入的字符串
protected FilterResults performFiltering(CharSequence constraint) {
// 首先取得FilterResults对象
FilterResults results = new FilterResults();
// 判断,如果输入框输入的字符串为空,那么不错处理,listview中的字符集全部返回,返回对象为FilterResults;
if (constraint == null || constraint.length() == 0) {
List<String> values = new ArrayList<String>();
results.values = values;
results.count = 0;
} else {
//先创建一个空字符集,用来存放返回字符集
List<String> newValues = new ArrayList<String>();
//为了不去分大小写匹配,故把匹配字段和listview的字符集都转换为小写来匹配
String lconstraint = constraint.toString().toLowerCase();
//用一个foreach循环,用输入字符串匹配listview的每个字符串
for (int i = 0; i < filterlists.size(); i++) {
String str = filterlists.get(i).toLowerCase();
//当匹配时,newValues添加相应字符串
if (str.indexOf(lconstraint) != -1) {
newValues.add(str);
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
//设置listview显示的字符集,并调用notifyDataSetChanged()方法,更新UI界面
lists = (List<String>) results.values;
notifyDataSetChanged();
}
}
}
上面adapter中需要一个布局文件,很简单的做个textview,这里不上代码了
主函数实现:MainActivity.java:
package com.min.mysearchview;
import java.util.ArrayList;
import java.util.List;
import android.R.integer;
import android.app.Activity;
import android.media.Image;
import android.os.Bundle;
import android.text.Html;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.Toast;
public class MainActivity extends Activity {
//定义SearchView
private SearchView sv;
private ListView lv;
//定义过滤器
private Filter filter;
//自定义适配器
MySearchAdapter adapter;
//提示字符集
List<String> hins;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
hins = new ArrayList<>();
hins.add("qq邮箱");
hins.add("qq空间");
hins.add("qq浏览器");
hins.add("qq邮箱");
hins.add("3q大战");
hins.add("大众点评");
hins.add("评论政客");
hins.add("论证之道");
hins.add("邮箱登录窗口");
//创建自定义的MySearchAdapter对象
adapter = new MySearchAdapter(hins, this);
//listview设置adapter
lv.setAdapter(adapter);
//listview设置不可见
lv.setVisibility(ListView.INVISIBLE);
sv = (SearchView) findViewById(R.id.sv);
//修改搜索图标
int search_logo_id=sv.getContext().getResources().getIdentifier("android:id/search_mag_icon", null, null);
ImageView search_logo=(ImageView) findViewById(search_logo_id);
//要替换的资源图标
search_logo.setImageResource(R.drawable.search2);
//需改queryHint字体的颜色
sv.setQueryHint(Html.fromHtml("<font color = #ff0000>" + "输入关键字" + "</font>"));
//获取过滤器
filter = ((Filterable) adapter).getFilter();
//事件监听,第一个是提交的监听,第二个为输入搜索框字改变的监听
sv.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
//简单来个toast,需要其他功能具体再实现
Toast.makeText(getApplicationContext(), query,
Toast.LENGTH_LONG).show();
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
//如果没有输入字,传递给过滤器的参数为null
if (newText == null || newText.length() == 0) {
filter.filter(null);
} else {
//先设置listview可见,传递输入的字符串作为参数给过滤器
lv.setVisibility(ListView.VISIBLE);
filter.filter(newText);
}
return true;
}
});
}
}