(4.0.26)Android之Filter过滤数据

一、何谓Android的过滤机制?

Android对数据的处理是分层的,从上到下,可以分为:数据层、提供层、Cursor层(不好意思,没找到一个词来表示)、适配层、显示层。每个层次通过一定的机制,可以使数据发生变化时能够上下通知。如下图:

  • 显示层(ListView,GridView,AutoCompleteTextView等)
  • 适配层(Adpater)
  • Cursor层(Cursor)
  • 提供层(ContentProvider)
  • 数据层(文件、sqlite、SharedPreference)

数据层是数据具体的存储方式,它可以包括文件、sqlite数据库以及SharedPreference。提供层向上层提供了统一的数据调用方式,并负责向其它应用共享数据。Cursor层将查询的数据统一成Cursor的形式来使用。适配层用来连接Cursor层和显示层,将数据和界面连接起来。显示层负责数据的显示。

另外,Andriod提供了数据的过滤机制,也就是在不改变数据存储的情况下,异步或同步的过滤符合条件的数据,并即时的显示在界面上。

Android原生的例子当中,最明显的例子就是AutoCompleteTextView
这里写图片描述
当输入“C程”时,数据库中自动过滤出了还有该字符串的联系人姓名,并显示出来。

二、Android做了哪些?

  1. 为了实现数据的过滤,andorid设计了抽象类Filter,进行异步和同步的数据过滤操作。
  2. 在Adapter中继承Filterable,提供给使用者Filter,进行过滤。
  3. 在不同的View中,获得查询约束字符串,传递给Adapter,并且提供配合数据过滤的界面支持。

三、Filter类

Filter的使用流程如下:

调用filter方法->在另一线程中调用performFiltering进行数据查询->得到数据过滤结果后调用publishResults将结果返回到使用它的客户端。

该类中的performFiltering和publishResults均为抽象方法,需要继承者自己重写。

四、Filterable接口

常用的Adapter基本上都继承了Filterable接口,如CursorAdapter,ArrayAdapter,SimpleAdapter等。该接口只有一个函数,名为getFilter,通过该函数可以通过Adaper获取Filter,然后通过该Filter进行过滤。

五、数据过滤功能的View的界面支持。

为了实现数据过滤的功能,在数据显示层,也有相应的支持。比如ListView和GridView,设置了setFilterText函数,通过该函数可以一方面进行数据的过滤,另一方面显示一个PopupWindow,提示用户输入了那种过滤条件。AutoCompleteTextView当用户在文本框输入文字时,自动进行过滤,并弹出列表显示过滤数据。

六、实战

MainActivity如下:

package cc.testfilterable;

import java.util.ArrayList;
import java.util.HashMap;
import android.os.Bundle;
import android.widget.ListView;
import android.app.Activity;
import android.content.Context;
/**
 * Demo描述:
 * 利用Filter过滤数据
 * 可用于AutoCompleteTextView筛选数据等功能
 * 
 * 备注说明:
 * 该Demo只表述原理,代码逻辑较简单,有一些小的bug.
 * 完整的应用请参见以下资料.
 * 
 * 参考资料:
 * 1 http://gundumw100.iteye.com/blog/1446507
 * 2 http://blog.csdn.net/ssstudio/article/details/7579089
 * 3 http://blog.csdn.net/jiahui524/article/details/7802033
 * 
 */
public class MainActivity extends Activity {
  private Context mContext;
    private ListView mListView;
    private ListViewAdapter mListViewAdapter;
    private ArrayList<String> mArrayList;
    private HashMap<String, String> mHashMap;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    init();
  }

  private void init(){
    mContext=this;
    mListView=(ListView) findViewById(R.id.listView);
    mArrayList=new ArrayList<String>();
    mArrayList.add("张三1");
    mArrayList.add("李四1");
    mArrayList.add("王五1");
    mArrayList.add("张三2");
    mArrayList.add("李四2");
    mArrayList.add("王五2");
    mArrayList.add("张三3");
    mArrayList.add("李四3");
    mArrayList.add("王五3");
    mArrayList.add("张三4");
    mArrayList.add("李四4");
    mArrayList.add("王五4");
    mListViewAdapter=new ListViewAdapter(mContext, mArrayList);
    //过滤数据
    //过滤出姓名里面包含"张"的数据
    mListViewAdapter.getFilter().filter("张");
    mListView.setAdapter(mListViewAdapter);
  }

}

ListViewAdapter如下:

package cc.testfilterable;

import java.util.ArrayList;
import java.util.Iterator;
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.TextView;

public class ListViewAdapter extends BaseAdapter {
  private NameFilter mNameFilter;
  private List<String> mArrayList;
  private List<String> mFilteredArrayList;
  private LayoutInflater mLayoutInflater;
  public ListViewAdapter(Context context,List<String> arrayList) {
    mArrayList = arrayList;
    mLayoutInflater=LayoutInflater.from(context);
    mFilteredArrayList=new ArrayList<String>();
  }

  @Override
  public int getCount() {
    if (mArrayList == null) {
      return 0;
    } else {
      return (mArrayList.size());
    }

  }

  @Override
  public Object getItem(int position) {
    if (mArrayList == null) {
      return null;
    } else {
      return mArrayList.get(position);
    }
  }

  @Override
  public long getItemId(int position) {
    return position;
  }
  
  public Filter getFilter() {  
       if (mNameFilter == null) {    
    	   mNameFilter = new NameFilter();    
       }    
      return mNameFilter;  
    }  


  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View itemView = null;
    itemView = convertView;
    ViewHolder viewHolder = null;
    if (itemView == null) {
      itemView = mLayoutInflater.inflate(R.layout.listviewitem, null);
      viewHolder = new ViewHolder();
      viewHolder.textView = (TextView) itemView.findViewById(R.id.textView);
      itemView.setTag(viewHolder);
    } else {
      viewHolder = (ViewHolder) itemView.getTag();
    }

    if (mArrayList != null) {
      if (viewHolder.textView != null) {
        viewHolder.textView.setText((mArrayList.get(position)));
      }

    }

    convertView = itemView;
    return convertView;
  }
  

  private class ViewHolder {
    TextView textView;
  }
  
  
  //过滤数据
  class NameFilter extends Filter {
    //执行筛选
    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
      FilterResults filterResults = new FilterResults();
      for (Iterator<String> iterator = mArrayList.iterator(); iterator.hasNext();) {
        String name = iterator.next();
        System.out.println("---> name=" + name);
        if (name.contains(charSequence)) {
          mFilteredArrayList.add(name);
        }
      }
      filterResults.values = mFilteredArrayList;
      return filterResults;
    }

    //筛选结果
    @Override
    protected void publishResults(CharSequence arg0, FilterResults results) {
      mArrayList = (List<String>) results.values;
      if (results.count > 0) {
        notifyDataSetChanged();
      } else {
        notifyDataSetInvalidated();
      }

    }}
  
}
<RelativeLayout 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"
    >

    <ListView
        android:id="@+id/listView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
     />

</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
     >
    <TextView 
       android:id="@+id/textView"
       android:layout_width="wrap_content"
       android:layout_height="50dip"
       android:gravity="center"
    />    
   
</LinearLayout>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值