Moayed I. Alayseh Moayed I. Alayseh - 29 days ago 14
Android Question

Android filter recycler view data from retroft

i have this recycler view and i get data from retroft api , the problem is when i tried to make filter in recycler , i search in the internet and all example is list of strings , but i have list of objects , how i can solve this case and create filter in the toolbar ? i will post my code and hope anyone to help , thank you

Activity

public class TodoList extends AppCompatActivity implements DialogFragUpdateListener {
RecyclerView todoRecyclerView;
private RecyclerView.Adapter todoAdapter;
private RecyclerView.LayoutManager todoLayoutManager;
public List<ToDo> results;
public List<String> list = new ArrayList<>();


TodoRecyclerAdapter recyclerAdapter;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_todo_list);


todoRecyclerView = (RecyclerView)findViewById(R.id.todoRecyclerView);
todoRecyclerView.setHasFixedSize(true);
results= new ArrayList<ToDo>();


todoLayoutManager = new LinearLayoutManager(this);
todoRecyclerView.setLayoutManager(todoLayoutManager);


FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(TodoList.this,AddToDo.class);
startActivity(intent);
}
});}

public void getRetrofitObject() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
Call<Result> call = service.getresults();
call.enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {

results = response.body().getResults();
if(recyclerAdapter == null){

recyclerAdapter = new TodoRecyclerAdapter(this,results);
todoRecyclerView.setAdapter(recyclerAdapter);
}
else{

recyclerAdapter.setData(results);
recyclerAdapter.notifyDataSetChanged();
}

}
@Override
public void onFailure(Call<Result> call, Throwable t) {
Log.d("onFailure", t.toString());
}});}

@Override
public void OnDBUpdate() {


Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
Call<Result> call = service.getresults();
call.enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {
results = response.body().getResults();
if(recyclerAdapter == null){

recyclerAdapter = new TodoRecyclerAdapter(this,results);
todoRecyclerView.setAdapter(recyclerAdapter);
}
else{

recyclerAdapter.setData(results);
recyclerAdapter.notifyDataSetChanged();
}
}
@Override
public void onFailure(Call<Result> call, Throwable t) {
Log.d("onFailure", t.toString());
}});
}




@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {

@Override
public void onFocusChange(View v, boolean hasFocus) {

}
});

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

@Override
public boolean onQueryTextSubmit(String query) {
recyclerAdapter.getFilter().filter(query);
return false;
}

@Override
public boolean onQueryTextChange(String searchQuery) {

return true;
}
});

MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
});
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

int id = item.getItemId();

if (id == R.id.action_search) {

return true;
}
return super.onOptionsItemSelected(item);
}}


and this is Adapter

public class TodoRecyclerAdapter extends RecyclerView.Adapter<TodoRecyclerAdapter.ViewHolder> {
static List<ToDo> todoResults;
static Context context;
List<ToDo>results;
ArrayList<ToDo> arraylist;
private List<String> mDefaultCheeses;



public TodoRecyclerAdapter(Callback<Result> callback, List<ToDo> results) {
this.todoResults = results;
arraylist = new ArrayList<ToDo>();
arraylist.addAll(todoResults);

}
@Override
public TodoRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.todo_items, null);
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
@Override
public void onBindViewHolder(final TodoRecyclerAdapter.ViewHolder holder, final int position) {
holder.todoTitle.setText(todoResults.get(position).getTODO_TITLE().toString());
String priority = todoResults.get(position).getPriority().toString();
if (priority.equals("Low")) {
holder.todoImage.setImageResource(R.drawable.low);
} else if (priority.equals("Normal")) {
holder.todoImage.setImageResource(R.drawable.normal);
} else if (priority.equals("High")) {
holder.todoImage.setImageResource(R.drawable.high);
}
}


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

public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView todoTitle;
public ImageView todoImage;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
todoTitle = (TextView) itemLayoutView.findViewById(R.id.todo_title);
todoImage = (ImageView) itemLayoutView.findViewById(R.id.imageView2);
}}


and this is menu

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.android.nigeriaexams.ui.SettingsFragment">
<item android:id="@+id/action_search"
android:title="Search"
android:icon="@drawable/ic_search"
app:showAsAction="collapseActionView|always"
app:actionViewClass="android.support.v7.widget.SearchView"
android:layout_width="wrap_content" />



Answer

You can implement Filterable interface in adapter and can do like this

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

        static List<ToDo> todoResults;
        static Context context;
        List<ToDo>results;
        ArrayList<ToDo> arraylist;
        private List<String> mDefaultCheeses;

        private ToDoListFilter listFilter;

        private List<ToDo> mData;
        private List<ToDo> originalData;


        public TodoRecyclerAdapter(Callback<Result> callback, List<ToDo> results) {
            this.todoResults = results;
            arraylist = new ArrayList<ToDo>();
            arraylist.addAll(todoResults);

        }

        public List<ChatListData> getData() {
            return mData;
        }

        public void setData(List<ChatListData> mData) {
            this.mData = mData;

            if (originalData == null) {
                originalData = mData;
            }
        }

        @Override
        public TodoRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.todo_items, null);
            ViewHolder viewHolder = new ViewHolder(itemLayoutView);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(final TodoRecyclerAdapter.ViewHolder holder, final int position) {
            holder.todoTitle.setText(todoResults.get(position).getTODO_TITLE().toString());
            String priority = todoResults.get(position).getPriority().toString();
            if (priority.equals("Low")) {
                holder.todoImage.setImageResource(R.drawable.low);
            } else if (priority.equals("Normal")) {
                holder.todoImage.setImageResource(R.drawable.normal);
            } else if (priority.equals("High")) {
                holder.todoImage.setImageResource(R.drawable.high);
            }
        }

         @Override
            public Filter getFilter() {
                if (listFilter == null)
                    listFilter = new ToDoListFilter(this,originalData);

                return listFilter;
            }

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

        public static class ViewHolder extends RecyclerView.ViewHolder {
            public TextView todoTitle;
            public ImageView todoImage;
            public ViewHolder(View itemLayoutView) {
                super(itemLayoutView);
                todoTitle = (TextView) itemLayoutView.findViewById(R.id.todo_title);
                todoImage = (ImageView) itemLayoutView.findViewById(R.id.imageView2);
            }
        }


        private class ToDoListFilter extends Filter {

            private final TodoRecyclerAdapter listAdapter;

            private final List<ToDo> originalData;
            private List<ToDo> filteredData;

            public ToDoListFilter(TodoRecyclerAdapter listAdapter, List<ToDo> originalData) {
                this.listAdapter = listAdapter;
                this.originalData = originalData;
                this.filteredData = new ArrayList<>();
            }

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

                Log.d("performFiltering: " , constraint.toString());

                if (TextUtils.isEmpty(constraint.toString())) {
                    filteredData.addAll(originalData);
                } else {
                    final String filterPattern = constraint.toString().toLowerCase().trim();

                    for (final ToDo user : originalData) {
                        // set condition for filter here
                        if (user.getToUserName().toLowerCase().contains(filterPattern)) {
                            filteredData.add(user);
                        }
                    }
                }

                results.values = filteredData;
                results.count = filteredData.size();
                return results;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {

                //listAdapter.getData().clear();
                listAdapter.setData((List<ToDo>) filterResults.values);
                listAdapter.notifyDataSetChanged();

            }
        }
    }

And to call this

listAdapter.getFilter().filter(query);

For more check here

Hope it will solve your problem...