編輯:關於Android編程
實現ListView過濾功能最方便的便是使用ArrayAdapter,裡面自帶的getFilter()方法能很方便的實現此功能
但是在實際的開發中,ArrayAdapter有的時候滿足不了我們項目的各種需求,所以一般都是繼承於BaseAdapter,然後繼承BaseAdapter不能像ArrayAdapter那樣直接通過ListView的setTextFilter()就對ListView進行簡單的過濾,我們需要去手動實現一個Filterable接口,自定義過濾規則;
首先先上效果圖接下來直接上代碼了
* 首先是布局文件<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
視圖布局就是
* SearchFragment.java
/** * @author鄭明亮 @email [email protected] * @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"; Listdata = 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); //暫時模擬填充數據 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(搜素框)設置一個TextWatcher來監視輸入的動作 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());//設置過濾關鍵字 } @Override public void afterTextChanged(Editable editable) { } }); } private void initData(){ data = new ArrayList<>(); data.add(new Recomend("應用推薦","忙碌一天的你,怎麼能沒有一款好玩的游戲來放松一下呢")); data.add(new Recomend("好書推薦","讀過一本好書,像交了一個益友。——臧克家")); data.add(new Recomend("養生推薦","三天不吃青,兩眼冒金星。寧可食無肉,不可飯無湯。吃面多喝湯,免得開藥方")); data.add(new Recomend("資訊推薦","風聲雨聲讀書聲,聲聲入耳;家事國事天下事,事事關心,快來看看吧")); data.add(new Recomend("更多推薦","吃喝玩樂學一應俱全,快來看看吧")); data.add(new Recomend("更多推薦","吃喝玩樂學一應俱全,快來看看吧")); data.add(new Recomend("更多推薦","吃喝玩樂學一應俱全,快來看看吧")); data.add(new Recomend("更多推薦","吃喝玩樂學一應俱全,快來看看吧")); 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();//搜索文本為空時,過濾設置 }else { // search_list.clearTextFilter(); search_list.setFilterText(search);//設置過濾關鍵字 } break; default: break; } } }
我在注釋中已經注明了,需要注意的地方就是一定要先打開過濾功能 search_list.setTextFilterEnabled(true)
* 接下來是適配器的代碼,關鍵代碼;
/** * @author 鄭明亮 @email [email protected] * @version 1.0 * @time 2016/7/29 18:28 * TODO */ public class RecomendAdapter extends BaseAdapter implements Filterable{ Context context; Listdata; //這個數據是會改變的,所以要有個變量來備份一下原始數據 List backData;//用來備份原始數據 MyFilter mFilter ; public RecomendAdapter(Context context, List 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; } //當ListView調用setTextFilter()方法的時候,便會調用該方法 @Override public Filter getFilter() { if (mFilter ==null){ mFilter = new MyFilter(); } return mFilter; } //我們需要定義一個過濾器的類來定義過濾規則 class MyFilter extends Filter{ //我們在performFiltering(CharSequence charSequence)這個方法中定義過濾規則 @Override protected FilterResults performFiltering(CharSequence charSequence) { FilterResults result = new FilterResults(); List list ; if (TextUtils.isEmpty(charSequence)){//當過濾的關鍵字為空的時候,我們則顯示所有的數據 list = backData; }else {//否則把符合條件的數據對象添加到集合中 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 )filterResults.values; LogUtil.d("publishResults:"+filterResults.count); if (filterResults.count>0){ notifyDataSetChanged();//通知數據發生了改變 LogUtil.d("publishResults:notifyDataSetChanged"); }else { notifyDataSetInvalidated();//通知數據失效 LogUtil.d("publishResults:notifyDataSetInvalidated"); } } } }
顯示效果: 我在參考鏈接中看到了作者的仿的qq提示框,但是在使用的時候並不是很方面,有一些不足,於是我參照Android系統AlertDialog
知識點目錄 5.1 滑動效果是如何產生的 5.1.1 Android坐標系 5.1.2 視圖坐標系 5.1.3 觸控事件——MotionEvent
故事概況:小農在開發的時候隊長叫本人封裝一個工具類,直接調用就能調起系統通訊錄,選擇人員後,把電話號碼帶回到UI……..於是故事開始了&hel
RecyclerView已經出來很久了,許許多多的項目都開始從ListView轉戰RecyclerView,那麼,上拉加載和下拉刷新是一件很有必要的事情。在ListVie