Reputation: 13
i have a RecyclerView and an EditText, when the search is typed it will filter out the items. but when the search is clicked it just passes the first unfiltered search. here is my code.
here is the FoodAdapter
..
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ProductViewHolder> {
private Context mCtx;
private static List<FoodModel> productList;
private OnNoteListener monNoteListener;
//getting the context and product list with constructor
public FoodAdapter(Context mCtx, List<FoodModel> productList, OnNoteListener onNoteListener) {
this.mCtx = mCtx;
this.productList = productList;
this.monNoteListener = onNoteListener;
}
public void filteredList(List<FoodModel> filteredList) {
productList = filteredList;
notifyDataSetChanged();
}
@Override
public ProductViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.sam_layout_products, null);
return new ProductViewHolder(view,monNoteListener);
}
@Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
//getting the product of the specified position
FoodModel product = productList.get(position);
//binding the data with the viewholder views
holder.txtFoodName.setText(product.getFoodName());
holder.txtFoodDesc.setText(product.getFoodDesc());
holder.txtFoodPrice.setText(product.getFoodPrice());
holder.imageView.setImageDrawable(mCtx.getResources().getDrawable(product.getFoodImage()));
}
@Override
public int getItemCount() {
return productList.size();
}
public class ProductViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView txtFoodName, txtFoodDesc, txtFoodPrice;
ImageView imageView;
OnNoteListener onNoteListener;
public ProductViewHolder(View itemView, OnNoteListener onNoteListener) {
super(itemView);
txtFoodName = itemView.findViewById(R.id.txtFood);
txtFoodDesc = itemView.findViewById(R.id.txtFoodDesc);
txtFoodPrice = itemView.findViewById(R.id.txtFoodPrice);
imageView = itemView.findViewById(R.id.imageView);
this.onNoteListener = onNoteListener;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
onNoteListener.onNoteClick(getAdapterPosition());
}
}
public interface OnNoteListener{
void onNoteClick(int position);
}
}
and here is the activity FoodActivity
public class FoodsActivity extends AppCompatActivity implements FoodAdapter.OnNoteListener {
private DrawerLayout dl;
private ActionBarDrawerToggle t;
private NavigationView nv;
static List<FoodModel> FoodList;
static List<FoodModel> filteredList;
//the recyclerview
RecyclerView recyclerView;
String NameString;
FoodAdapter foodAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.foods_layout);
setTitle("Foods");
RecyclerViewFood();
EditText txtFoodSearch = findViewById(R.id.txtFoodSearch);
txtFoodSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence query, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
SearchFilter(editable.toString());
}
});
}
@Override
public void onNoteClick(int position) {
Intent intent = new Intent(this, sample_layout.class);
intent.putExtra("foods", FoodList.get(position));
startActivity(intent);
}
private void SearchFilter(String text){
recyclerView = (RecyclerView) findViewById(R.id.FoodRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
filteredList = new ArrayList<>();
for(FoodModel item: FoodList){
if(item.getFoodName().toLowerCase().contains(text.toLowerCase())){
filteredList.add(item);
}
}
foodAdapter = new FoodAdapter(this,filteredList,this);
// what can i do to pass the correct item to the next intent
recyclerView.setAdapter(foodAdapter);
}
public void RecyclerViewFood() {
recyclerView = (RecyclerView) findViewById(R.id.FoodRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FoodList = new ArrayList<>();
String food_name[] = getResources().getStringArray(R.array.food_name);
String food_desc[] = getResources().getStringArray(R.array.food_desc);
String food_price[] = getResources().getStringArray(R.array.food_price);
int food_image[] = {R.drawable.pic_chickenpizza, R.drawable.pic_dorowot, R.drawable.pic_genfo, R.drawable.pic_kitfo, R.drawable.pic_tibs};
for (int i = 0, j = 0, k = 0, l = 0; i < food_name.length; i++, j++, k++, l++) {
FoodList.add(new FoodModel(2, food_name[i], food_desc[j], food_price[k], food_image[l]));
}
//creating recyclerview adapter
foodAdapter= new FoodAdapter(this, FoodList, this);
//setting adapter to recyclerview
recyclerView.setAdapter(foodAdapter);
}
when the search is entered, it works but when the filteredList is clicked its passing the wrong item to the next intent.
Upvotes: 1
Views: 134
Reputation: 13
Nevermind, i removed the old setOnClickListener and made a new one in the onBindViewHolder with the following code
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mCtx, sample_layout.class);
intent.putExtra("foods", productList.get(position));
mCtx.startActivity(intent);}
});
and now its working. thank you all for your answers :)
Upvotes: 0
Reputation: 866
This is in continuation for the errors you might be facing in @Prince Ali's code. Make these changes to have context passed to your intent
public class ProductViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView txtFoodName, txtFoodDesc, txtFoodPrice;
ImageView imageView;
OnNoteListener onNoteListener;
View mView; //Add this line
public ProductViewHolder(View itemView, OnNoteListener onNoteListener) {
super(itemView);
txtFoodName = itemView.findViewById(R.id.txtFood);
txtFoodDesc = itemView.findViewById(R.id.txtFoodDesc);
txtFoodPrice = itemView.findViewById(R.id.txtFoodPrice);
imageView = itemView.findViewById(R.id.imageView);
this.onNoteListener = onNoteListener;
itemView.setOnClickListener(this);
mView = itemView; // Add this line
}
Now in your onClick method
Context mCtx = holder.mView.getContext();
startMyActivity ( mCtx , filterList.get(getAdapterPosition() ).getId() );
// method
private void startMyActivity ( Context context , long id ) {
Intent intent = new Intent( context , sample_layout.class);
intent.putExtra("foods", id );
context.startActivity(intent);
}
Upvotes: 1
Reputation: 770
First, your adapter implements Filterable
.
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ProductViewHolder> implements Filterable {
// Filtered list
private List<FoodModel> filterList;
// Normal list
private List<FoodModel> productList;
In your constructor:
this.filterList = productList;
productList = new ArrayList<>(productList);
Implementing Filterable requires overriding the getFilter()
method.
Filtering the list:
@Override
public Filter getFilter() {
return MyFilter;
}
private Filter MyFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
List<FoodModel> filteredList = new ArrayList<>();
if (constraint == null || constraint.length() == 0) {
filteredList.addAll(productList);
} else {
String filterPattern = constraint.toString().trim();
for (FoodModel item : productList) {
if (item.getFoodName().contains(filterPattern)) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filterList.clear();
filterList.addAll((List) results.values);
notifyDataSetChanged();
}
};
This is important that you use the filtered list inside onBindViewHolder:
FoodModel product = filterList.get(position);
Now in your activity:
@Override
public void afterTextChanged(Editable editable) {
String newText = editable.toString();
adapter.getFilter().filter(newText);
}
Edit: get size of the filtered list instead of normal list:
@Override
public int getItemCount() {
return filterList.size();
}
In your adapter's onClick:
startMyActivity ( mCtx , filterList.get(getAdapterPosition() ).getId() );
// method
private void startMyActivity ( Activity activity , long id ) {
Intent intent = new Intent( activity , sample_layout.class);
intent.putExtra("foods", id );
activity.startActivity(intent);
}
Upvotes: 1