Generic Adapter with search and sort functionality I have tried to create a GenericAdapter that can help you search, sort automatically without writing a lot of code.


But in order to use this you have to follow some rules. How can I make it better and where am I not using a better approach. 

rules for using GenericAdapter.


extends your business model with BaseModel
extends your viewHolder with BaseViewHolder
your adapter must extends GenericAdapter


where

BaseModel.class

public abstract class BaseModel&lt;T&gt; implements Comparator&lt;T&gt;
{
   public abstract String getAttributeToSearch();
   ///public abstract int whatYouWantToCompare();
}


BaseViewHolder.class

public abstract class BaseViewHolder&lt;T extends BaseModel&gt; extends RecyclerView.ViewHolder 
{

  public BaseViewHolder(View itemView) {
    super(itemView);
  }

  public abstract void bindData(T data);
}


GenericBaseAdapter.class

public abstract class GenericBaseAdapter&lt;T extends BaseModel, U extends BaseViewHolder&gt; extends RecyclerView.Adapter&lt;U&gt; implements Filterable {

    private Context mContext;
    private List&lt;T&gt; itemList;
    private List&lt;T&gt; origList;

    public GenericBaseAdapter(Context mContext, List&lt;T&gt; itemList) {
        this.mContext = mContext;
        this.itemList = itemList;
        this.origList = itemList;
    }

    @Override
    public void onBindViewHolder(U holder, int position) {
        holder.bindData(itemList.get(position));
    }

    @Override
    public int getItemCount() {
        return itemList.size();
    }

    public T getItem(int position) {
        return itemList.get(position);
    }

    public void setItems(List&lt;T&gt; itemList) {
        this.itemList = itemList;
        this.origList = itemList;
        notifyDataSetChanged();
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                final FilterResults oReturn = new FilterResults();
                final ArrayList&lt;T&gt; results = new ArrayList&lt;&gt;();
                if (origList == null)
                    origList = new ArrayList&lt;&gt;(itemList);
                if (constraint != null &amp;&amp; constraint.length() &gt; 0) {
                    if (origList != null &amp;&amp; origList.size() &gt; 0) {
                        for (final T cd : origList) {
                            if (cd.getAttributeToSearch().toLowerCase()
                                    .contains(constraint.toString().toLowerCase()))
                                results.add(cd);
                        }
                    }
                    oReturn.values = results;
                    oReturn.count = results.size();//newly Aded by ZA
                } else {
                    oReturn.values = origList;
                    oReturn.count = origList.size();//newly added by ZA
                }
                return oReturn;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(final CharSequence constraint,
                                          FilterResults results) {
                itemList = new ArrayList&lt;&gt;((ArrayList&lt;T&gt;) results.values);
                // FIXME: 8/16/2017 implement Comparable with sort below
                ///Collections.sort(itemList);
                notifyDataSetChanged();
            }
        };
    }

    public void sortItems(T obje) {
        Collections.sort(itemList, obje);
        notifyDataSetChanged();
    }
}


for sorting use

mAdapter.sortItems(productList.get(0));


for searching.. 

mAdapter.getFilter().filter("any string to search");
Here are some suggestions take what you like from it:


You can make BaseModel an interface. This gives the added benefit that your models do not need to extend your abstract class.
In your getFilter method in a code review I'd ask you to put curly braces around your first if.

if (origList == null) {
    origList = new ArrayList&lt;&gt;(itemList);
}
You can instantiate your filter once as a member of the class, rather than instantiating a new one every time the function getFilter is called.
Use collections.unmodifiablelist to protect yourself from unwanted mutations of the original list, when creating or assigning a new list. This is just a precautionary suggestion that has performance implications. Your not mutating when you should not be.