1、技术概述
- 技术概述
利用数据适配器类实现列表搜索功能。
- 原因
需要为用户提供搜索筛选功能,方便用户快速查找信息。
- 难点
数据适配器及过滤器类的书写,数据刷新显示。
2、技术详述
最初在网上查阅了大量的代码,通过阅读多分代码比较会发现他们的一些相同的地方,这部分就是这个功能的关键部分了,然后仔细阅读这部分的代码,大致搞懂它的实现逻辑之后就自己动手参照着写代码了。实现过程如下:
- 写一个类实现适配器接口,用于适配需要展示的列表数据
/**
*数据适配器
*
*/
class RecomendAdapter extends BaseAdapter implements Filterable {
Context context;
List<Periodic> data; //这个数据是会改变的,所以要有个变量来备份一下原始数据
List<Periodic> backData;//用来备份原始数据
MyFilter mFilter ;
public RecomendAdapter(Context context, List<Periodic> data) {
this.context = context;
this.data = data;
backData = data;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int i) {
return data.get(i);
}
@Override
public long getItemId(int i) {
return 0;
}
public void addItem(Periodic obj){
data.add(obj);
}
public void removeItem(int index){
Periodic tep = data.get(index);
backData.remove(tep);
data.remove(tep);
}
public void clearAll(){
data.clear();
backData.clear();
}
public void setData(List<Periodic> data){
this.data = data;
backData = data;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
if (view ==null){
view = LayoutInflater.from(context).inflate(R.layout.periodic_list_item,null);
}
//从数组中得到数据并然后给页面组件设置值
Periodic periodicItem=data.get(position);
TextView nameView = (TextView)view.findViewById(R.id.periodic_item_name);
TextView moneyView = (TextView)view.findViewById(R.id.periodic_item_money);
TextView startView = (TextView)view.findViewById(R.id.periodic_item_start);
TextView endView = (TextView)view.findViewById(R.id.periodic_item_end);
//设置periodic项目的值,信息
//时间格式化
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String tmpMoney=null;
if(periodicItem.getType()==0){//支出
tmpMoney = "-" + String.valueOf(periodicItem.getPeriodic_money());
moneyView.setTextColor(Color.parseColor("#ff0000"));
}
else {//收入
tmpMoney = "+" + String.valueOf(periodicItem.getPeriodic_money());
moneyView.setTextColor(Color.parseColor("#00ff00"));
}
nameView.setText(periodicItem.getPeriodic_name());
moneyView.setText(String.valueOf(periodicItem.getPeriodic_money()));
startView.setText(format.format(periodicItem.getStart()));
endView.setText(format.format(periodicItem.getEnd()));
return view;
}
/**
* 当ListView调用setTextFilter()方法的时候,便会调用该方法
* @return 过滤器类
*/
@Override
public Filter getFilter() {
if (mFilter ==null){
mFilter = new MyFilter();
}
return mFilter;
}
}
- 写一个过滤类根据用户输入进行数据筛选,并刷新数据
/**
* 定义一个过滤器的类来定义过滤规则
*/
class MyFilter extends Filter{
/**
* 义过滤规则
* @param charSequence 输入的字符文本
* @return
*/
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults result = new FilterResults();
List<Periodic> list ;
if (TextUtils.isEmpty(charSequence)){//当过滤的关键字为空的时候,我们则显示所有的数据
list = backData;
}else {//否则把符合条件的数据对象添加到集合中
list = new ArrayList<>();
for (Periodic recomend:backData){
if (recomend.getPeriodic_name().contains(charSequence)){
list.add(recomend);
}
}
}
result.values = list; //将得到的集合保存到FilterResults的value变量中
result.count = list.size();//将集合的大小保存到FilterResults的count变量中
return result;
}
/**
* 告诉适配器更新界面
* @param charSequence
* @param filterResults
*/
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
data = (List<Periodic>)filterResults.values;
if (filterResults.count>0){
notifyDataSetChanged();//通知数据发生了改变
}else {
notifyDataSetInvalidated();//通知数据失效
}
}
}
- 为列表注册适配器并添加搜索框事件响应处理
searchPeriodic.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
/**
* 当点击搜索按钮时触发该方法
* @param query 输入的字符串
* @return
*/
@Override
public boolean onQueryTextSubmit(String query) {
//提交搜索后的处理逻辑
return false;
}
/**
* 当搜索内容改变时触发该方法,时刻监听输入搜索框的值
* @param newText 当前输入的文本
* @return
*/
@Override
public boolean onQueryTextChange(String newText) {
//如果newText长度不为0
if (TextUtils.isEmpty(newText)){
//清除ListView的过滤
listView.clearTextFilter();
}else{
//使用用户输入的内容对ListView的列表项进行过滤
listView.setFilterText(newText);
}
return true;
}
});
3、遇到的问题和解决方法
- 列表数据不刷新
每次更改数据后要调用数据适配器的notifyDataSetChanged() 方法通知数据的变化
4、总结
最初列表展示的适配器是简单的数组适配器,并不能满足搜索的功能需求,在查阅资料后发现需要重写适配器才能达到功能需求,刚开始感觉这挺难的,但好在网上的资料足够丰富,也找到了一些例子可供参考,最后还是实现了这个功能。总之,遇到困难要抱着积极的态度去尝试解决。