2

I've use Filterable inside my RecyclerView. What I wanted to do is, to filter the recyclerview from edittext. Below is my actual code.

public class NavDrawerAdapter_v2 extends RecyclerView.Adapter<NavDrawerAdapter_v2.ViewHolder> implements Filterable{

private static final int TYPE_ITEM = 0;

private ArrayList<String> menu_list;
private ArrayList<String> filtered_menu_list;
Context mContext;

public static class ViewHolder extends RecyclerView.ViewHolder {
    int Holderid;

    TextView shopName, shopLevel;

    public ViewHolder(View itemView,int ViewType) {
        super(itemView);

        shopName = (TextView) itemView.findViewById(R.id.rowText);
        shopLevel = (TextView) itemView.findViewById(R.id.rowLevel);

        if(ViewType == TYPE_ITEM) {
            Holderid = 0;
        }
    }
}

public NavDrawerAdapter_v2(Context mContext, ArrayList<String> menu_list){
    this.menu_list = menu_list;
    this.filtered_menu_list = menu_list;
    this.mContext = mContext;
}

@Override
public NavDrawerAdapter_v2.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    if (viewType == TYPE_ITEM) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_item_row,parent,false); //Inflating the layout
        return new ViewHolder(v,viewType);
    }

    return null;
}

@Override
public void onBindViewHolder(NavDrawerAdapter_v2.ViewHolder holder, int position) {

    if (holder.Holderid == 0) {
        String getShopName = menu_list.get(position).split("-")[0];
        String getShopLevel = menu_list.get(position).split("-")[1];
        holder.shopName.setText(getShopName);
        holder.shopLevel.setText(getShopLevel);
    }
}

@Override
public int getItemCount() {
    return menu_list == null ? 0 : menu_list.size();
}

@Override
public long getItemId(int position) {
    return super.getItemId(position);
}

@Override
public int getItemViewType(int position) {

    return TYPE_ITEM;
}

public boolean okay(){
    return true;
}

@Override
public Filter getFilter() {
    return new UserFilter(this, menu_list);
}

private static class UserFilter extends Filter {

    private final NavDrawerAdapter_v2 adapter;

    private final ArrayList<String> originalList;

    private final ArrayList<String> filteredList;

    private UserFilter(NavDrawerAdapter_v2 adapter, ArrayList<String>originalList) {
        super();
        this.adapter = adapter;
        this.originalList = new ArrayList<>(originalList);
        this.filteredList = new ArrayList<>();
    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        filteredList.clear();
        final FilterResults results = new FilterResults();

        if (constraint.length() == 0) {
            filteredList.addAll(originalList);
        } else {
            final String filterPattern = constraint.toString().toLowerCase().trim();

            for (String getValue : originalList) {
                if (getValue.contains(filterPattern)) {
                    filteredList.add(getValue);
                }
            }
        }
        results.values = filteredList;
        results.count = filteredList.size();
        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        adapter.filtered_menu_list.clear();
        adapter.filtered_menu_list.addAll((ArrayList<String>) results.values);
        adapter.notifyDataSetChanged();
    }
}

}

But, in my fragment. I can't call adapter.getFilter(). What is wrong here?

Azizi Musa
  • 1,009
  • 2
  • 10
  • 31

2 Answers2

0

If you want EditText for searchView purposes, you need to add change listener for EditText, as explained in the link : android on Text Change Listener

When the text changed, you should call

adapter.getFilter().filter(newText);

Alternatively, you should try to implement searchview in action bar with recyclerView. Todo this, implement getFilter() method inside your RecyclerView adapter. You can use the getFilter() method implemented in the link https://stackoverflow.com/a/10532898/1308990 .

menu.xml:

<item android:id="@+id/menuSearch"
  android:title="search"
  android:icon = "@android:drawable/ic_menu_search"
  app:actionViewClass = "android.support.v7.widget.SearchView"
  app:showAsAction = "always|collapseActionView"></item>

Inside onCreateOptionsMenu() method, write following codes :

MenuItem item = menu.findItem(R.id.menuSearch);
//SearchView searchView = (SearchView) item.getActionView(); 
SearchView searchView =  (SearchView) MenuItemCompat.getActionView(item); 

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

//Called when the query text is changed by the user.
@Override
public boolean onQueryTextChange(String newText) {
    Log.d("soda in MainActivity","onQueryTextChange method is called.");
    mutfagimFragment.adapter.getFilter().filter(newText);
    return false;
}
});

When the user changes the text, check whether the onQueryTextChange() method is called by monitoring the logs. If it is not called, try to put the above codes inside onPrepareOptionsMenu() method rather than onCreateOptionsMenu() method.

oiyio
  • 5,219
  • 4
  • 42
  • 54
0

Following your example, I'm pretty sure you were assigning the object to a RecyclerView.Adapter variable instead of to a NavDrawerAdapter_v2 variable inside the Activity.

RecyclerView.Adapter adapter = new NavDrawerAdapter_v2(menuList);

instead of

NavDrawerAdapter_v2 adapter = new NavDrawerAdapter_v2(menuList);

NavDrawerAdapter_v2 extends from RecyclerView.Adapter but at the same time implements Filterable.

If you assign the object to a RecyclerView.Adapter variable you will still be able to call getItemCount(), onBindViewHolder() and onCreateViewHolder() (since they are abstract methods from RecyclerView.Adapter)

The bad part is that you won't be able to call getFilter() because it belongs to the Filterable interface.

pkdpqowjodiv
  • 123
  • 1
  • 7