简体   繁体   中英

Android filter recycler view data from Retrofit

i have this recycler view and i get data from Retrofit 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" />

Add a filter() method to your custom Adapter .

private ArrayList<ToDo> arraylist = null, toDoArrayList;

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

public void filter(String filterString) {
    filterString = filterString.toLowerCase(Locale.getDefault());
    arraylist.clear();
    if (filterString.length() == 0) {
        arraylist.addAll(toDoArrayList);
    }
    else {
        for (ToDo toDO : toDoArrayList) {
            if(toDO.getYourSearchValue().toLowerCase(Locale.getDefault()).contains(filterString)) {
                arraylist.add(toDO);
            }
        }
    }
    notifyDataSetChanged();
}

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...

I have tried below code : I think it will work.

public class SearchAdapter extends RecyclerView.Adapter implements Filterable {

private ItemFilter itemFilter;
private ArrayList<CommonModel> arrayList;//filtered emoji collection
private ArrayList<CommonModel> fullList;//Full emoji collection
private Context context;

public SearchAdapter(final Context context, final ArrayList<CommonModel> arrayList) {
    this.arrayList = arrayList;
    this.fullList = arrayList;
    this.context = context;
    itemFilter = new ItemFilter();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_search, parent, false);
    final ViewHolder viewHolder = new ViewHolder(view);
    return viewHolder;
}

@Override
public void onBindViewHolder(KeyboardEmojiSearchAdapter.ViewHolder holder, int position) {
    final CommonModel commonModel = arrayList.get(position);

    Glide.with(context).load(commonModel.getDisplayImage()).asBitmap().into(holder.iv);
}

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

@Override
public Filter getFilter() {
    return itemFilter;
}

/**
 * Holder class to hold grid item
 */
public static class ViewHolder extends RecyclerView.ViewHolder {
    private ImageView iv;


    public ViewHolder(View view) {
        super(view);
        iv = (ImageView) view.findViewById(R.id.row_search_iv);

    }
}

/**
 * Filter class allows filtering by tags from Emoji collection
 */
private class ItemFilter extends Filter {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        final FilterResults results = new FilterResults();
        final ArrayList<CommonModel> newFilteredList = new ArrayList<>();

        if (constraint.toString().trim().length() > 0) {

            final String filterString = constraint.toString().toLowerCase();
            final int count = fullList.size();

            for (int i = 0; i < count; i++) {
                for (int j = 0; j < fullList.get(i).getTagList().size(); j++) {
                    if (fullList.get(i).getTagList().get(j).toLowerCase().startsWith(filterString)) {
                        newFilteredList.add(fullList.get(i));
                        break;
                    }
                }
            }
        } else {
            newFilteredList.addAll(fullList);
        }

        results.values = newFilteredList;
        results.count = newFilteredList.size();

        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        arrayList = (ArrayList<CommonModel>) results.values;
        notifyDataSetChanged();
    }
}

Please refer below code.

edtSearch.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            gridAdapter.getFilter().filter(charSequence);
        }

        @Override
        public void afterTextChanged(Editable editable) {
        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM