Reputation: 117
I have a Search filter which has to filter the items based on the text input. Each list item consists of two TextViews and one ImageView. I have attached adapters and the filter is working fine with the two textviews but the corresponding ImageViews are not getting filtered (the order of images is not changing). I tried to change the code in several ways but its not working. In here, my Adapter extends ArrayAdapter. I tried using the BaseAdapter too, but still doesn't work
My Adapter class:
import de.hdodenhof.circleimageview.CircleImageView;
public class ChefSearchResultAdapter extends ArrayAdapter<ChefSearchItem> implements Filterable {
private ArrayList<ChefSearchItem> modelValues;
private List<ChefSearchItem> mOriginalValues;
private Context context;
private static class ViewHolder {
TextView userName;
TextView userAdmirers;
CircleImageView userProfileImage;
}
public ChefSearchResultAdapter(Context context, ArrayList<ChefSearchItem> chefs) {
super(context, 0, chefs);
modelValues = chefs;
this.context=context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
ChefSearchItem chef = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
final ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
// If there's no view to re-use, inflate a brand new view for row
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.chef_search_listitem, parent, false);
viewHolder.userName = convertView.findViewById(R.id.user_name);
viewHolder.userAdmirers = convertView.findViewById(R.id.user_admirers);
viewHolder.userProfileImage = convertView.findViewById(R.id.profile_image);
// Cache the viewHolder object inside the fresh view
convertView.setTag(viewHolder);
} else {
// View is being recycled, retrieve the viewHolder object from tag
viewHolder = (ViewHolder) convertView.getTag();
}
final StorageReference storageReference = FirebaseStorage.getInstance().getReference("Users").child(chef.userUID);
storageReference.child("Profile Pic").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
//Picasso.get().load(uri).into(viewHolder.userProfileImage);
Picasso.get()
.load(uri)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(viewHolder.userProfileImage, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError(Exception e) {
Picasso.get()
.load(uri)
.into(viewHolder.userProfileImage, new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onError(Exception e) {
Log.v("Picasso","Could not fetch image");
}
});
}
});
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
// Populate the data from the data object via the viewHolder object
// into the template view.
viewHolder.userName.setText(chef.userName);
viewHolder.userAdmirers.setText(chef.userAdmirers);
//Set on click to listitem
LinearLayout listItem = convertView.findViewById(R.id.chef_listitem);
listItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Navigate user to selected chef profile
Intent i=new Intent(context,ChefsViewActivity.class);
i.putExtra("UID",chef.userUID);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
});
// Return the completed view to render on screen
return convertView;
}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
modelValues.clear();
modelValues.addAll((ArrayList<ChefSearchItem>) results.values);
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// Holds the results of a filtering values
List<ChefSearchItem> FilteredArrList = new ArrayList<>();
if (mOriginalValues == null) {
mOriginalValues = new ArrayList<>(modelValues); // saves
}
/********
*
* If constraint(CharSequence that is received) is null returns
* the mOriginalValues(Original) values else does the Filtering
* and returns FilteredArrList(Filtered)
*
********/
if (constraint == null || constraint.length() == 0) {
// set the Original result to return
results.count = mOriginalValues.size();
results.values = mOriginalValues;
} else {
Locale locale = Locale.getDefault();
constraint = constraint.toString().toLowerCase(locale);
for (int i = 0; i < mOriginalValues.size(); i++) {
ChefSearchItem model = mOriginalValues.get(i);
String data = model.userName;
if (data.toLowerCase(locale).contains(constraint.toString())) {
FilteredArrList.add(model);
}
}
// set the Filtered result to return
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}
return results;
}
};
return filter;
}
}
My ViewHolder:
public class ChefSearchItem {
public String userName;
public String userAdmirers;
public String userUID;
public ChefSearchItem(String userName, String userAdmirers, String userUID) {
this.userName = userName;
this.userAdmirers = userAdmirers;
this.userUID = userUID;
}
}
Upvotes: 0
Views: 42
Reputation: 106
More simpler way to filter out data is filter them locally
In your activity where your searchview is on submit call this method and pass the search string as parameter. Make a temporary list which will consist of filterdata.
filter(String filter){
ArrayList<ChefSearchItem> filtereModelValues = new ArrayList<ChefSearchItem>();
for (ChefSearchItem chefSearchItem : <LIST YOU ARE SENDING TO ADAPTER>){
if(filter.toLowerCase().equals(chechefSearchItem.userUID.toLowerCase())
filtereModelValues.add(chefSearchItem );
}
//outside the for loop send the filtered list to adapter by creating method inside adapter name "filter" and pass filterList as parameter.
YOUR_ADAPTER.filter(filtereModelValues);
}
And in your adapter
public void filter(ArrayList<ChefSearchItem> filterModelValues){
modelValues = filterModelValues;
notifyDataChanged();
}
Upvotes: 1