Android實現(xiàn)ListView過濾功能之繼承BaseAdapter(轉(zhuǎn))

作者:zml_2015
原文:https://blog.csdn.net/zml_2015/article/details/52082174

實現(xiàn)ListView過濾功能最方便的便是使用ArrayAdapter亲配,里面自帶的getFilter()方法能很方便的實現(xiàn)此功能

但是在實際的開發(fā)中,ArrayAdapter有的時候滿足不了我們項目的各種需求罕偎,所以一般都是繼承于BaseAdapter吱抚,然后繼承BaseAdapter不能像ArrayAdapter那樣直接通過ListView的setTextFilter()就對ListView進行簡單的過濾朱巨,我們需要去手動實現(xiàn)一個Filterable接口糕再,自定義過濾規(guī)則撒顿;
效果圖


image.png
image.png

接下來直接上代碼了

  • 首先是布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@color/white"
              android:orientation="vertical"
    >

    <LinearLayout
        android:id="@+id/search_top_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="@color/blue_title_bg"
        android:gravity="center_vertical"
        android:orientation="horizontal" >


        <com.zml.collrec.view.AutoClearEditText
            android:id="@+id/search_edit"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:background="@drawable/search_box"
            android:drawableRight="@drawable/app_icon_voice"
            android:focusable="true"
            android:hint="搜索"
            android:padding="6dp"
            android:singleLine="true"
            android:textColor="@color/black"
            android:textSize="@dimen/micro_text_size" />

        <ImageButton
            android:id="@+id/search_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="#035AB2"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:src="@mipmap/android_search_icon" />
    </LinearLayout>

    <ListView
        android:id="@+id/search_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/search_top_layout"
        android:divider="@null"
        android:dividerHeight="1dp"
        android:listSelector="@null"
        android:scrollbars="none"
         />

    </LinearLayout>

布局視圖


image.png
 
* SearchFragment.java

/**
 * @author鄭明亮    @email 1072307340@qq.com
 * @Time:2016/8/1 1:35
 * @version 1.0
 * TODO
 */public class SearchFragment extends Fragment implements AdapterView.OnItemClickListener, View.OnClickListener {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    List<Recomend>data = null;
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    RecomendAdapter adapter = null;

    private OnFragmentInteractionListener mListener;

    AutoClearEditText et_search;//我自定義的EditText
    ImageButton ib_search;
    ListView search_list;



    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment SearchFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static SearchFragment newInstance(String param1, String param2) {
        SearchFragment fragment = new SearchFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_search, container, false);

        initView(view);
        //暫時模擬填充數(shù)據(jù)
        initData();
        return view;
    }

    private void initView(View view) {
        ib_search = (ImageButton) view.findViewById(R.id.search_button);
        et_search = (AutoClearEditText) view.findViewById(R.id.search_edit);
        search_list = (ListView) view.findViewById(R.id.search_list);
        search_list.setTextFilterEnabled(true); // 開啟過濾功能
        ib_search.setOnClickListener(this);
        //為EditText(搜素框)設(shè)置一個TextWatcher來監(jiān)視輸入的動作
        et_search.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                if (TextUtils.isEmpty(charSequence.toString().trim()))
                    search_list.clearTextFilter();//搜索文本為空時扯再,清除ListView的過濾
                else
                search_list.setFilterText(charSequence.toString().trim());//設(shè)置過濾關(guān)鍵字
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });

    }

    private void initData(){
        data = new ArrayList<>();
        data.add(new Recomend("應(yīng)用推薦","忙碌一天的你离熏,怎么能沒有一款好玩的游戲來放松一下呢"));
        data.add(new Recomend("好書推薦","讀過一本好書佳谦,像交了一個益友∽檀粒——臧克家"));
        data.add(new Recomend("養(yǎng)生推薦","三天不吃青钻蔑,兩眼冒金星啥刻。寧可食無肉,不可飯無湯矢棚。吃面多喝湯郑什,免得開藥方"));
        data.add(new Recomend("資訊推薦","風(fēng)聲雨聲讀書聲,聲聲入耳蒲肋;家事國事天下事蘑拯,事事關(guān)心,快來看看吧"));
        data.add(new Recomend("更多推薦","吃喝玩樂學(xué)一應(yīng)俱全兜粘,快來看看吧"));
        data.add(new Recomend("更多推薦","吃喝玩樂學(xué)一應(yīng)俱全申窘,快來看看吧"));
        data.add(new Recomend("更多推薦","吃喝玩樂學(xué)一應(yīng)俱全,快來看看吧"));
        data.add(new Recomend("更多推薦","吃喝玩樂學(xué)一應(yīng)俱全孔轴,快來看看吧"));
        adapter = new RecomendAdapter(getActivity(),data);
        search_list.setAdapter(adapter);
        search_list.setOnItemClickListener(this);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        ScreenUtils.showToast(data.get(i).getTitle());
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.search_button:
                String search = et_search.getText().toString().trim();
                if (TextUtils.isEmpty(search)){
                    search_list.clearTextFilter();//搜索文本為空時剃法,過濾設(shè)置
                }else {
//                    search_list.clearTextFilter();
                    search_list.setFilterText(search);//設(shè)置過濾關(guān)鍵字
                }


                break;
            default:
                break;
        }
    }

}

我在注釋中已經(jīng)注明了,需要注意的地方就是一定要先打開過濾功能 search_list.setTextFilterEnabled(true)

  • 接下來是適配器的代碼路鹰,關(guān)鍵代碼贷洲;
/**
 * @author 鄭明亮   @email 1072307340@qq.com
 * @version 1.0
 * @time 2016/7/29 18:28
 * TODO
 */
public class RecomendAdapter extends BaseAdapter implements Filterable{
    Context context;
    List<Recomend> data; //這個數(shù)據(jù)是會改變的,所以要有個變量來備份一下原始數(shù)據(jù)
    List<Recomend> backData;//用來備份原始數(shù)據(jù)
    MyFilter mFilter ;

    public RecomendAdapter(Context context, List<Recomend> data) {
        this.context = context;
        this.data = data;
        backData = data;
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {

        if (view ==null){
            view = LayoutInflater.from(context).inflate(R.layout.fragment_recomend_item,null);
       }
        TextView tv_title = ViewHolder.get(view,R.id.tv_recomend_title);
        TextView tv_desc = ViewHolder.get(view,R.id.tv_recomend_desc);
        ImageView img = ViewHolder.get(view,R.id.iv_recomend_img);
        tv_title.setText(data.get(i).getTitle());
        tv_desc.setText(data.get(i).getDesc());
        Glide.with(context).load(R.drawable.default_head_icon).asBitmap().centerCrop().placeholder(R.mipmap.ic_launcher).into(img);
        return view;
    }
    //當(dāng)ListView調(diào)用setTextFilter()方法的時候晋柱,便會調(diào)用該方法
    @Override
    public Filter getFilter() {
        if (mFilter ==null){
            mFilter = new MyFilter();
        }
        return mFilter;
    }
    //我們需要定義一個過濾器的類來定義過濾規(guī)則
     class MyFilter extends Filter{
     //我們在performFiltering(CharSequence charSequence)這個方法中定義過濾規(guī)則
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            FilterResults result = new FilterResults();
            List<Recomend> list ;
              if (TextUtils.isEmpty(charSequence)){//當(dāng)過濾的關(guān)鍵字為空的時候优构,我們則顯示所有的數(shù)據(jù)
                list  = backData;
            }else {//否則把符合條件的數(shù)據(jù)對象添加到集合中
                list = new ArrayList<>();
                for (Recomend recomend:backData){
                    if (recomend.getTitle().contains(charSequence)||recomend.getDesc().contains(charSequence)){
                        LogUtil.d("performFiltering:"+recomend.toString());
                        list.add(recomend);
                    }

                }
            }
            result.values = list; //將得到的集合保存到FilterResults的value變量中
            result.count = list.size();//將集合的大小保存到FilterResults的count變量中

            return result;
        }
    //在publishResults方法中告訴適配器更新界面
        @Override
        protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
            data = (List<Recomend>)filterResults.values;
            LogUtil.d("publishResults:"+filterResults.count);
            if (filterResults.count>0){
                notifyDataSetChanged();//通知數(shù)據(jù)發(fā)生了改變
                LogUtil.d("publishResults:notifyDataSetChanged");
            }else {
                notifyDataSetInvalidated();//通知數(shù)據(jù)失效
                LogUtil.d("publishResults:notifyDataSetInvalidated");
            }
        }
    }
}

最后用search_list.setFilterText(search);//設(shè)置過濾關(guān)鍵字 會出現(xiàn)如效果圖出現(xiàn)的黑色的框
可以使用adapter.getFilter().filter(s)就不會有那個框框了 。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雁竞,一起剝皮案震驚了整個濱河市钦椭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碑诉,老刑警劉巖彪腔,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異进栽,居然都是意外死亡德挣,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門快毛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盲厌,“玉大人,你說我怎么就攤上這事祸泪。” “怎么了建芙?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵没隘,是天一觀的道長。 經(jīng)常有香客問我禁荸,道長右蒲,這世上最難降的妖魔是什么阀湿? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮瑰妄,結(jié)果婚禮上陷嘴,老公的妹妹穿的比我還像新娘。我一直安慰自己间坐,他們只是感情好灾挨,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著竹宋,像睡著了一般劳澄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜈七,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天秒拔,我揣著相機與錄音,去河邊找鬼飒硅。 笑死砂缩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的三娩。 我是一名探鬼主播庵芭,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼尽棕!你這毒婦竟也來了喳挑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤滔悉,失蹤者是張志新(化名)和其女友劉穎伊诵,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體回官,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡曹宴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了歉提。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笛坦。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖苔巨,靈堂內(nèi)的尸體忽然破棺而出版扩,到底是詐尸還是另有隱情,我是刑警寧澤侄泽,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布礁芦,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏柿扣。R本人自食惡果不足惜肖方,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望未状。 院中可真熱鬧俯画,春花似錦、人聲如沸司草。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翻伺。三九已至材泄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吨岭,已是汗流浹背拉宗。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辣辫,地道東北人旦事。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像急灭,于是被迫代替她去往敵國和親姐浮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容