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);}
});
现在可以正常使用了。
谢谢大家的回答:)
我有一个 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);}
});
现在可以正常使用了。 谢谢大家的回答:)