package com.cncoderx.recyclerviewhelper.adapter; import android.net.Uri; import androidx.annotation.IdRes; import androidx.annotation.LayoutRes; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Checkable; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @author cncoderx */ public class SimpleAdapter extends BaseAdapter implements Filterable { private int[] mTo; private String[] mFrom; private ViewBinder mViewBinder; private List> mData; private int mResource; private SimpleFilter mFilter; private ArrayList> mUnfilteredData; public SimpleAdapter(List> data, @LayoutRes int resource, String[] from, @IdRes int[] to) { mData = data; mResource = resource; mFrom = from; mTo = to; } @Override protected View onCreateView(LayoutInflater inflater, ViewGroup parent, int viewType) { return inflater.inflate(mResource, parent, false); } @Override public void onBindViewHolder(BaseViewHolder holder, int position) { final Map dataSet = mData.get(position); if (dataSet == null) return; final ViewBinder binder = mViewBinder; final String[] from = mFrom; final int[] to = mTo; final int count = to.length; for (int i = 0; i < count; i++) { final View v = holder.getView(to[i]); if (v != null) { final Object data = dataSet.get(from[i]); String text = data == null ? "" : data.toString(); if (text == null) { text = ""; } boolean bound = false; if (binder != null) { bound = binder.setViewValue(v, data, text); } if (!bound) { if (v instanceof Checkable) { if (data instanceof Boolean) { ((Checkable) v).setChecked((Boolean) data); } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else { throw new IllegalStateException(v.getClass().getName() + " should be bound to a Boolean, not a " + (data == null ? "" : data.getClass())); } } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else if (v instanceof ImageView) { if (data instanceof Integer) { setViewImage((ImageView) v, (Integer) data); } else { setViewImage((ImageView) v, text); } } else { throw new IllegalStateException(v.getClass().getName() + " is not a " + " view that can be bounds by this SimpleAdapter"); } } } } } @Override public int getItemCount() { return mData.size(); } public Object getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } public ViewBinder getViewBinder() { return mViewBinder; } public void setViewBinder(ViewBinder viewBinder) { mViewBinder = viewBinder; } public void setViewImage(ImageView v, int value) { v.setImageResource(value); } public void setViewImage(ImageView v, String value) { try { v.setImageResource(Integer.parseInt(value)); } catch (NumberFormatException nfe) { v.setImageURI(Uri.parse(value)); } } public void setViewText(TextView v, String text) { v.setText(text); } @Override public Filter getFilter() { if (mFilter == null) { mFilter = new SimpleFilter(); } return mFilter; } public static interface ViewBinder { boolean setViewValue(View view, Object data, String textRepresentation); } private class SimpleFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); if (mUnfilteredData == null) { mUnfilteredData = new ArrayList>(mData); } if (prefix == null || prefix.length() == 0) { ArrayList> list = mUnfilteredData; results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(); ArrayList> unfilteredValues = mUnfilteredData; int count = unfilteredValues.size(); ArrayList> newValues = new ArrayList>(count); for (int i = 0; i < count; i++) { Map h = unfilteredValues.get(i); if (h != null) { int len = mTo.length; for (int j = 0; j < len; j++) { String str = (String) h.get(mFrom[j]); String[] words = str.split(" "); int wordCount = words.length; for (int k = 0; k < wordCount; k++) { String word = words[k]; if (word.toLowerCase().startsWith(prefixString)) { newValues.add(h); break; } } } } } results.values = newValues; results.count = newValues.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { //noinspection unchecked mData = (List>) results.values; notifyDataSetChanged(); } } }