RecyclerView onClick returns 错误项目

RecyclerView onClick returns false item

我有一个 RecyclerView 和一个 EditText,当键入搜索时,它会过滤掉项目。但是当单击搜索时,它只会通过第一个未过滤的搜索。这是我的代码。

这里是 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);
    }

}

这里是 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);
    }

当输入搜索时,它起作用了,但是当点击 filteredList 时,它会将错误的项目传递给下一个意图。

首先,你的适配器implements Filterable

public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.ProductViewHolder> implements Filterable {

// Filtered list
private List<FoodModel> filterList;
// Normal list
private List<FoodModel> productList;

在你的构造函数中:

this.filterList = productList;
productList = new ArrayList<>(productList);

实现 Filterable 需要覆盖 getFilter() 方法。 筛选列表:

@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();
        }
    };

使用 onBindViewHolder 中的过滤列表很重要:

FoodModel product = filterList.get(position);

现在在你的 activity:

@Override
      public void afterTextChanged(Editable editable) {
        String newText = editable.toString();
        adapter.getFilter().filter(newText);
  }

编辑:获取过滤列表的大小而不是普通列表:

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

在您的适配器的 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);
}

这是您在@Prince Ali 的代码中可能遇到的错误的后续。进行这些更改以将上下文传递给您的意图

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
        }

现在在你的 onClick 方法中

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);
}

没关系,我删除了旧的 setOnClickListener 并使用以下代码在 onBindViewHolder 中创建了一个新的

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);}

});

现在可以正常使用了。 谢谢大家的回答:)