searchview EditText with Recyclerview - android

I am trying to add search functionality in my recyclerview. I found a tutorial on google and implemented the same. Search using editText in recyclerview. But my list disappears when I enter the input. Where am I going wrong? My recycler view contains multiple textboxes. Below is MyAdapter class.
How do I implement search functionality with the below code?
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>implements Filterable {
private List<ListItem> listItems;
private List<ListItem> mFilterData;
private Context context;
String m,e;
private ItemFilter mFilter = new ItemFilter();
public MyAdapter(List<ListItem> itemList, Context context) {
this.listItems = itemList;
this.context = context;
this.mFilterData = listItems;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ListItem listItem = mFilterData.get(position);
holder.nameText.setText(listItem.getName());
holder.addText.setText(listItem.getAddress());
Picasso.with(context).load(listItem.getLogo()).resize(180,80).into(holder.imageText);
}
#Override
public int getItemCount() {
return mFilterData.size();
}
public int getCount() {
return mFilterData.size();
}
public ListItem getItem(int position) {
return mFilterData.get(position);
}
public long getItemId(int position) {
return position;
}
#Override
public Filter getFilter() {
return mFilter;
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String userString = constraint.toString().toLowerCase();
FilterResults filterResults = new FilterResults();
final List<ListItem> originalList = listItems;
int count = originalList.size();
final ArrayList<ListItem> resultList = new ArrayList<>(count);
ListItem tDescription;
for (int i = 0; i < count; i++) {
tDescription= originalList.get(i);
if (tDescription.getName().toLowerCase().contains(userString)) {
resultList.add(tDescription);
}
}
filterResults.values = resultList;
filterResults.count = resultList.size();
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mFilterData = (ArrayList<ListItem>) results.values;
notifyDataSetChanged();
}
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView nameText, addText,mobText,emailText;
public ImageView imageText;
public ViewHolder(View itemView) {
super(itemView);
//code
}
}
}
SEARCH
private void addTextListener() {
search.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
s = s.toString().toLowerCase();
final List<ListItem> filteredList = new ArrayList<>();
for (int i = 0; i < listItems.size(); i++) {
final String text = listItems.get(i).toString();
if (text.contains(s)) {
filteredList.add(listItems.get(i));
}
}
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new MyAdapter(filteredList, getActivity());
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged(); // data set changed
}
});
}

Try below code
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String userString = constraint.toString().toLowerCase();
if (userString.isEmpty()) {
mFilterData = listItems;
} else {
ArrayList<ListItem> resultList = new ArrayList<>();
for (ListItem mListItem : listItems) {
if (mListItem.getName().toLowerCase().contains(userString)) {
resultList.add(mListItem);
}
}
mFilterData = resultList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mFilterData;
filterResults.count = mFilterData.size();
return filterResults;
}
}
Updated
Remove all code from edittext OnTextChange and write below code,no need to set adapter and all just write below oneline code and remove rest of code
adapter.getFilter().filter(s.toString());

Related

Android ArrayAdapter cant Filter because mOriginalValues not set

My Problem is that I cant Filter a ListView with a self defined Filter. The Filter prints out the needed Result but the View wont update.
This is my Activity :
public class RecipesActivity extends AppCompatActivity implements RecipeListFragment.OnListFragmentInteractionListener {
private TextView mTextMessage;
private ListView listView;
private RecipeListAdapter sIAdapter;
private EditText searchRecipe;
private ArrayList<Recipe> recipes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipes);
searchRecipe = (EditText) findViewById(R.id.searchRecipe);
mTextMessage = (TextView) findViewById(R.id.message);
recipes =SQLGetter.readRecipesFromDB(this,"");
listView = (ListView) findViewById(R.id.recipeList);
sIAdapter = new RecipeListAdapter(this,R.layout.recipe_list_row, recipes);
listView.setAdapter(sIAdapter);
searchRecipe.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
sIAdapter.getFilter().filter(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
}
This is my Adapter:
public class RecipeListAdapter extends ArrayAdapter<Recipe> implements Filterable {
private ArrayList<Recipe> arr;
private ArrayList<Recipe> filteredRecipes;
private TextView text;
public RecipeListAdapter(Context context, int textviewResourceId, ArrayList<Recipe> recipes){
super(context,textviewResourceId,recipes);
this.arr =recipes;
this.filteredRecipes=new ArrayList<Recipe>();
}
#Override
public View getView (final int position, View convertView, ViewGroup parent){
final Recipe recipe = getItem(position);
if(convertView==null) {
convertView= LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_list_row, parent, false);
}
final TextView recipeName = convertView.findViewById(R.id.recipeName);
recipeName.setText(recipe.getName());
if(!recipeName.getText().toString().isEmpty()) {
recipeName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), RecipeShowcaseActivity.class);
intent.putExtra("recipeName", recipe.getName());
getContext().startActivity(intent);
}
});
}
System.out.println("Arraygröße ="+ arr.size());
return convertView;
}
#Override
public Filter getFilter() {
final Filter filter = new Filter() {
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arr = (ArrayList<Recipe>) results.values;
System.out.println("Arrgröße : "+arr.size());
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
constraint = constraint.toString().toLowerCase();
ArrayList<Recipe> filteredList = new ArrayList<Recipe>();
ArrayList<Recipe> allRecipes =SQLGetter.readRecipesFromDB(getContext(),"");
for(Recipe recipe:allRecipes){
if(recipe.getName().toUpperCase().contains(constraint.toString().toUpperCase())){
filteredList.add(recipe);
}
}
System.out.println("Filterlistengröße: " +filteredList.size());
results.count = filteredList.size();
results.values = filteredList;
Log.e("VALUES", results.values.toString());
return results;
}
};
return filter;
}
}
And lastly this is the Problem I'm facing while calling the Filter in RecipesActivity :
enter image description here
In every post I've read so far, it's usually written that, mOriginalValues should be set because of the initiation
sIAdapter = new RecipeListAdapter(this,R.layout.recipe_list_row, recipes);
I'm really out of Ideas what I'm doing wrong here..
you should use sIAdapter.notifyDataSetChanged() after every time changes made in list.

How to get item position in viewholder when swipe with filtered text

I was able to get the value of the viewHolder.getAdapterPosition() but what Im after is when I search for items using Filter and tried to swipe the searched item it always gives me the position 0.
Example list:
0: Apple
1: Banana
2: Mango
3: Coconut
4: Peanut
I searched for peanut and it should be in the first item on the list but when I tried to swiped it always return 0 as apple.
Here is my code
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, final int direction) {
Log.e("ITEM ID", String.valueOf(viewHolder.viewHolder.getAdapterPosition());
adapters.notifyDataSetChanged();
}
Please see Adapter Class:
public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.MyViewHolder>{
private Context context;
private List<ProductObject> productList;
private double total;
private List<ProductObject> filteredItems;
private ProductsInterface productsInterface;
public interface ProductsInterface {
void productsInt(ProductObject position);
}
public void setProductsInterface(ProductsInterface productsInterfaceListener){
productsInterface = productsInterfaceListener;
}
public class MyViewHolder extends RecyclerView.ViewHolder{
ImageView img_url;
TextView prod_desc, prod_uom, prod_price, prod_quantity;
public MyViewHolder(View itemView, final ProductsInterface listener) {
super(itemView);
prod_desc = (TextView) itemView.findViewById(R.id.card_product_name);
prod_uom = (TextView) itemView.findViewById(R.id.card_uom);
prod_price = (TextView) itemView.findViewById(R.id.card_price);
img_url = (ImageView) itemView.findViewById(R.id.card_imageView);
prod_quantity = (TextView) itemView.findViewById(R.id.prod_quantity);
//listener.productsInt(filteredItems.get(getAdapterPosition()));
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null) {
//productsInterface.productsInt();
int position = getAdapterPosition();
Log.e("ADAPTER", String.valueOf(position));
if(position != RecyclerView.NO_POSITION){
listener.productsInt(filteredItems.get(getAdapterPosition()));
//ProductObject clickedItems = filteredItems.get(position);
}
}
}
});
}
}
public ProductsAdapter (Context context, List<ProductObject> listItems){
this.context = context;
this.productList = listItems;
this.filteredItems = listItems;
}
#Override
public ProductsAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_card_view, parent, false);
return new MyViewHolder(view, productsInterface);
}
#Override
public void onBindViewHolder(ProductsAdapter.MyViewHolder holder, int position) {
final ProductObject objectModel = filteredItems.get(holder.getAdapterPosition());
holder.prod_desc.setText(objectModel.getProd_desc());
holder.prod_uom.setText(objectModel.getProd_stockCode());
holder.prod_price.setText(String.valueOf(objectModel.getProd_price()));
holder.prod_quantity.setText(String.valueOf(objectModel.getProd_quantity()));
//prod id add here
/* Glide.with(context)
.load(objectModel.getProd_image())
.into(holder.img_url);*/
Glide.with(context)
.load(R.drawable.logo)
.into(holder.img_url);
}
#Override
public int getItemCount() {
return filteredItems.size();
}
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
if (charString.isEmpty()) {
filteredItems = productList;
} else {
final ArrayList<ProductObject> mFilteredList = new ArrayList<>();
for (final ProductObject listFilter : productList) {
if (listFilter.getProd_desc().toLowerCase().contains(charString) ||
listFilter.getProd_stockCode().toLowerCase().contains(charString)
) {
mFilteredList.add(listFilter);
}
}
filteredItems = mFilteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredItems;
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredItems = (ArrayList<ProductObject>) results.values;
notifyDataSetChanged();
}
};
}
}
Modify publishResults method to below
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredItems.clear();
filteredItems.addAll((ArrayList<ProductObject>) results.values);
notifyDataSetChanged();
}

Getting wrong item selected from filtered list using recyclerview

I have a RecyclerView & EditText. I can select the item from RecyclerView & gets correct item unless it is not filtered.
On entering in EditText, RecyclerView list gets filtered & when I select any item from the list it shows me actual list item instead of selected one.
Fragment Class :
public class RegionListFragment extends DialogFragment implements View.OnClickListener,
OnRecylerViewClickable {
private RecyclerView regionRecyclerView;
private ArrayList<RegionDetail> regionDetailArrayList = new ArrayList<>();
private GenericRegionListAdapter genericRegionListAdapter;
private Context context = this.getActivity();
private RecyclerView.LayoutManager mLayoutManager;
private View view;
private EditText editTextSearchView;
private DatabaseHandler spcl_databaseHandler;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.spinner_fragment_list_screen, container, false);
databaseHandler = new DatabaseHandler(getActivity());
regionDetailArrayList = (ArrayList<RegionDetail>) spcl_databaseHandler.getAllRegionDetails();
editTextSearchView = (EditText) view.findViewById( R.id.search);
editTextSearchView.setHint(getString(R.string.region_search_hint));
mLayoutManager = new LinearLayoutManager(context);
regionRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView_Locations);
regionRecyclerView.setLayoutManager(mLayoutManager);
relativeLayoutBottom = (RelativeLayout) view.findViewById(R.id.rlBottom);
genericRegionListAdapter = new GenericRegionListAdapter(context, regionDetailArrayList, this, false);
regionRecyclerView.setAdapter(genericRegionListAdapter);
addTextListener();
return view;
}
public void addTextListener(){
editTextSearchView.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence query, int start, int before, int count) {
genericRegionListAdapter.getFilter().filter(query.toString());
}
});
}
#Override
public void onClick(View view) {
}
#Override
public void onRecyclerItemClicked(int position, String itemName, String itemID) {
Log.v("Region Name", " : " + regionDetailArrayList.get(position).getRegionName());
}
}
Adapter Class :
public class GenericRegionListAdapter extends RecyclerView.Adapter<GenericRegionListAdapter.DataObjectHolder>
implements Filterable {
private ArrayList<RegionDetail> originalArrayList;
private ArrayList<RegionDetail> filterArrayList;
private GenericRegionListAdapter.ValueFilter valueFilter;
private OnRecylerViewClickable onRecylerViewClickable;
private Context mContext = null;
#Override
public GenericRegionListAdapter.DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.sd_custom_cardview_for_walk_list_item, parent, false);
GenericRegionListAdapter.DataObjectHolder dataObjectHolder = new GenericRegionListAdapter.DataObjectHolder(view);
return dataObjectHolder;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new GenericRegionListAdapter.ValueFilter();
}
return valueFilter;
}
public class DataObjectHolder extends RecyclerView.ViewHolder{
TextView textViewWalkName;
public DataObjectHolder(View itemView) {
super(itemView);
mContext = itemView.getContext();
textViewWalkName = (TextView) itemView.findViewById(R.id.textView_Walk_Name);
}
}
public GenericRegionListAdapter(Context context, ArrayList<RegionDetail> detailsArrayList,
OnRecylerViewClickable onRecylerViewClickable, boolean doShowCheckbox) {
mContext = context;
this.originalArrayList = detailsArrayList;
this.filterArrayList = detailsArrayList;
this.onRecylerViewClickable = onRecylerViewClickable;
}
#Override
public void onBindViewHolder(final GenericRegionListAdapter.DataObjectHolder holder, final int position) {
holder.textViewWalkName.setText(originalArrayList.get(position).getRegionName());
holder.textViewWalkName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onRecylerViewClickable.onRecyclerItemClicked(position, originalArrayList.get(position).getRegionName(), originalArrayList.get(position).getRegionID());
}
});
}
// method to access in activity after updating selection
public ArrayList<RegionDetail> getRegionList() {
return originalArrayList;
}
#Override
public int getItemCount() {
return originalArrayList.size();
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<RegionDetail> filterList = new ArrayList<RegionDetail>();
for (int i = 0; i < filterArrayList.size(); i++) {
if ((filterArrayList.get(i).getRegionName().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
RegionDetail listItem = new RegionDetail();
listItem.setRegionID(filterArrayList.get(i).getRegionID());
listItem.setRegionName(filterArrayList.get(i).getRegionName());
filterList.add(listItem);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = filterArrayList.size();
results.values = filterArrayList;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
originalArrayList = (ArrayList<RegionDetail>) results.values;
notifyDataSetChanged();
Log.v("Size", " : " + originalArrayList.size());
if (originalArrayList.size() == 0) {
new GlobalToast().showToastMessage(mContext, mContext.getResources().getString(R.string.no_records_found));
}
}
}
}
Please help me.
Please use this code snippet
private class ItemFilter extends Filter {
String filterString;
#Override
protected FilterResults performFiltering(CharSequence constraint) {
filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
int count = filterArrayList.size();
ArrayList<RegionDetail> filterList = new ArrayList<RegionDetail>();
String filterableString;
for (int i = 0; i < count; i++) {
RegionDetail listItem = new RegionDetail();
listItem.setRegionID(filterArrayList.get(i).getRegionID());
listItem.setRegionName(filterArrayList.get(i).getRegionName());
filterList.add(listItem);
}
results.values =filterList;
results.count = filterList.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
originalArrayList = (ArrayList<RegionDetail>) results.values;
notifyDataSetChanged();
}
}
i hope this code will filter your list correctly and you get right list item onClick.

Add a search filter on RecyclerView with Cards?

I found solutions for filters on ListView and SearchView on RecyclerView separately, but I wish to combine them. Is it even possible?
Yes it is possible Your RecyclerView.Adapter can implement Filterable. After that you have to override Filter getFilter() method.
You have to define your own filter as is shown in the code below:
#Override
public Filter getFilter() {
return new YourFilterClass();
}
YourFilterClass
class YourFilterClass extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
//Here you have to implement filtering way
final FilterResults results = new FilterResults();
//logic to filtering
results.values = ...
results.count = ...
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// here you can use result - (f.e. set in in adapter list)
}
}
Example
public class UserListAdapter extends RecyclerView.Adapter<UserListAdapter.ViewHolder> implements Filterable {
private final List<User> userList;
private final List<User> filteredUserList;
private UserFilter userFilter;
public UserListAdapter(Context context) {
this.userList =new ArrayList<>();
this.filteredUserList = new ArrayList<>();
}
///... other methods
#Override
public Filter getFilter() {
if(userFilter == null)
userFilter = new UserFilter(this, userList);
return userFilter;
}
private static class UserFilter extends Filter {
private final UserListAdapter adapter;
private final List<User> originalList;
private final List<User> filteredList;
private UserFilter(UserListAdapter adapter, List<User> originalList) {
super();
this.adapter = adapter;
this.originalList = new LinkedList<>(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 (final User user : originalList) {
if (user.getName().contains(filterPattern)) {
filteredList.add(user);
}
}
}
results.values = filteredList;
results.count = filteredList.size();
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.filteredUserList.clear();
adapter.filteredUserList.addAll((ArrayList<User>) results.values);
adapter.notifyDataSetChanged();
}
}
}
After that in the place when you want to filtering call:
userListAdapter.getFilter().filter(text)
Here is complete sample code
Model Class
public class Skills {
int id;
String skill;
boolean isSelected;
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
Adapter Class
private static final String TAG = SkillAdapter.class.getSimpleName();
protected List<Skills> mOriginalData = new ArrayList<>();
protected List<Skills> mResultData = new ArrayList<>();
protected Activity mActivity;
OnRecyclerViewClick onRecyclerViewClick;
private ItemFilter mFilter = new ItemFilter();
public SkillAdapter(Activity activity, OnRecyclerViewClick onRecyclerViewClick) {
mActivity = activity;
this.onRecyclerViewClick = onRecyclerViewClick;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_skill,
parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Skills data = mResultData.get(position);
try {
final ViewHolder viewHolder = (ViewHolder) holder;
if (data != null) {
viewHolder.checkSkill.setText(data.getSkill());
viewHolder.checkSkill.setChecked(data.isSelected());
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
return mResultData.size();
}
public void addItem(Skills exam) {
mOriginalData.add(exam);
mResultData.add(exam);
int index = mOriginalData.indexOf(exam);
notifyItemInserted(index);
}
public void removeItem(int index) {
mOriginalData.remove(index);
notifyItemRemoved(index);
}
public void removeItem(Skills exam) {
int index = mOriginalData.indexOf(exam);
mOriginalData.remove(exam);
notifyItemRemoved(index);
}
public Filter getFilter() {
return mFilter;
}
public Skills getItem(int index) {
return mOriginalData.get(index);
}
public void replaceItem(int index, Skills audioMeta) {
mOriginalData.set(index, audioMeta);
notifyItemChanged(index);
}
public class ViewHolder extends RecyclerView.ViewHolder {
CheckBox checkSkill;
public ViewHolder(View itemView) {
super(itemView);
checkSkill = (CheckBox) itemView.findViewById(R.id.chkSkill);
checkSkill.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onRecyclerViewClick.onItemClick(v, getLayoutPosition());
}
});
}
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
int count = mOriginalData.size();
final ArrayList<Skills> tempFilterList = new ArrayList<Skills>(count);
String filterableString;
for (int i = 0; i < count; i++) {
filterableString = mOriginalData.get(i).getSkill();
if (filterableString.toLowerCase().contains(filterString)) {
tempFilterList.add(mOriginalData.get(i));
}
}
results.values = tempFilterList;
results.count = tempFilterList.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mResultData.clear();
mResultData = (ArrayList<Skills>) results.values;
notifyDataSetChanged();
}
}
In Activity Use
mAdapter = new SkillAdapter(SkillsActivity.this, SkillsActivity.this);
recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
recyclerView.setAdapter(mAdapter);
Then Filter
editSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
mAdapter.getFilter().filter(editSearch.getText().toString());
}
});
Inside Fragment Class declare that:
protected List<User> mDataset;
protected List<User> mDataOrigin;
then inside onCreate add same source destination to both dataSet ant dataOrigin
mDataset = getObjectsFromDB();
mDataOrigin = getObjectsFromDB();
Finally use the magic function:
private void filterRecyclerView(String charText){
charText = charText.toLowerCase();
clearDataSet();
if (charText.length() == 0) {
mDataset.addAll(mDataOrigin);
} else {
for (User user : mDataOrigin) {
if (user.getName().toLowerCase().contains(charText)) {
mDataset.add(user);
}
}
}
mAdapter.notifyDataSetChanged();
}
Notice User is the list content you can replace with your Object have fun :)

Android Filter ListView by BaseAdapter

i'm try to write simple filtering ListView by this below code. but that does not work correctly
in this code i'm using ContactListStructure class structure as:
public class ContactListStructure implements Serializable {
public Long id;
public String name;
public String mobile;
public Bitmap photo;
public Boolean checked;
...
}
and i'm fill this class as an ArrayList with phone contacts. after fill that i'm set this list into ListView without any problem,then i'm try to fillter this list by:
/* private ArrayList<ContactListStructure> contact_item; */
contactsAdapter = new ContactsAdapter ( G.contact_item , ActivityContactList.this);
lstContent.setAdapter ( contactsAdapter );
search_contacts.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
contactsAdapter.getFilter().filter(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
POST UPDATE
search_contacts is an EditText and after type into that ListView dont filter and dont any change. my BaseAdapter :
public class ContactsAdapter extends BaseAdapter implements Filterable {
private Context mCtx=null;
private ArrayList<ContactListStructure> mData=null;
private ArrayList<ContactListStructure> arraylist;
private List<ContactListStructure> worldpopulationlist = null;
private ItemFilter mFilter = new ItemFilter();
static int i=0;
public ContactsAdapter (ArrayList<ContactListStructure> contact_item, Context ctx) {
mData=contact_item;
mCtx=ctx;
this.worldpopulationlist = contact_item;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public ContactListStructure getItem(int position) {
return worldpopulationlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null) {
LayoutInflater inflator=((Activity)mCtx).getLayoutInflater();
convertView=inflator.inflate(R.layout.send_sms,null);
}
CheckBox chk_name_mobile = (CheckBox)convertView.findViewById(R.id.chk_name_mobile);
ImageView photo = (ImageView)convertView.findViewById(R.id.photo);
String name=mData.get(position).name;
chk_name_mobile.setText(name);
if( mData.get(position).photo == null )
photo.setImageDrawable( G.context.getResources().getDrawable(R.drawable.user) );
else
photo.setImageBitmap(mData.get(position).photo);
return convertView;
}
#Override
public Filter getFilter () {
return mFilter;
}
private class ItemFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString();
FilterResults results = new FilterResults();
final ArrayList<ContactListStructure> list = mData;
int count = list.size();
final ArrayList<ContactListStructure> nlist = new ArrayList<ContactListStructure>(count);
String filterableString ;
for (ContactListStructure wp : worldpopulationlist)
{
if (wp.getName().contains(filterString))
{
//Log.e ("wp: ", String.valueOf ( wp ) );
ContactListStructure item = new ContactListStructure();
item.id = wp.id;
item.name = wp.name;
item.mobile = wp.mobile;
item.photo = wp.photo;
nlist.add(item);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arraylist = (ArrayList<ContactListStructure>) results.values;
notifyDataSetChanged();
}
}
}
UPDATE POST:
after help in comments my notifyDataSetChanged not working. after type into edit text thats can be find but listview dont refresh.
You can try following this question here: ListView is blank while using getFilter function
It was able to filter based on a choice from the ListView.
I think you forgot to add the data returned from result to your mData :
protected void publishResults(CharSequence constraint, FilterResults results) {
arraylist = (ArrayList<ContactListStructure>) results.values;
mData.clear();
for(int i = 0, i < arraylist.size(); i++)
mData.add(arraylist.get(i));
notifyDataSetChanged();
}
}

Categories

Resources