java - RecyclerView 适配器在奇怪的位置插入行
问题描述
我的Fragment
内部有一个MainActivity
包含一个RecyclerView
由RecyclerView.Adapter
. 具有 one和 one的RecyclerView
inflates文件,如下所示:row_layout.xml
EditText
ImageButton
该按钮最初加载了“添加”图像。单击后,我的适配器会执行以下操作:
package com.fragments.homework04;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
public static int positionAdapter;
private ArrayList<ItemData> itemsData;
AdapterButtonInterface mListener;
public MyAdapter(ArrayList<ItemData> itemsData, AdapterButtonInterface adapterButtonInterface) {
this.itemsData = itemsData;
try{
mListener = adapterButtonInterface;
}
catch(ClassCastException e){
throw new ClassCastException("Class does not implement interface!");
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public EditText txtIngredients;
public ImageView imgViewIcon;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
txtIngredients = itemLayoutView.findViewById(R.id.etIngredientName);
imgViewIcon = itemLayoutView.findViewById(R.id.btnAddRemoveIngredient);
}
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, null);
Log.d("itemsSizeAdapter", String.valueOf(itemsData.size()));
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
viewHolder.imgViewIcon.setTag(itemsData.get(position).getTag());
viewHolder.imgViewIcon.setImageResource(itemsData.get(position).getImageUrl());
viewHolder.imgViewIcon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
positionAdapter = viewHolder.getAdapterPosition();
if(itemsData.get(position).getTag().contains("Add")){
if(getItemCount() < 5){
itemsData.get(position).setIngredientValue(viewHolder.txtIngredients.getText().toString());
mListener.addBtnClicked(positionAdapter, getItemCount(), itemsData.get(position).getIngredientValue());
}
}
else{
if(getItemCount() > 0){
Log.d("adapterPosition:", String.valueOf(position));
mListener.removeBtnClicked(positionAdapter, getItemCount());
}
}
}
});
}
// Return the size of your itemsData (invoked by the layout manager)
@Override
public int getItemCount() {
return itemsData.size();
}
public interface AdapterButtonInterface{
void addBtnClicked(int position, int itemCount, String ingredientValue);
void removeBtnClicked(int position, int itemCount);
}
}
基本上调用接口中的方法,这是由我的片段实现的。在我的片段中,我正在这样做:
ArrayList<ItemData> itemsData;
public void addBtnClicked(int position, int itemCount, String ingredientValue) {
if(itemCount == 4){
//Requirement that there can only be 5 rows at any time.
//Hence when itemCount == 4, we are adding the 5th row and it needs to be a remove instead of add
itemsData.add(position + 1, new ItemData("Remove" + itemCount, R.mipmap.remove_ing, ""));
}
else{
itemsData.add(position + 1, new ItemData("Add" + itemCount, R.mipmap.add_ing, ""));
}
//When the row is added, the EditText's value isn't stored anywhere
//So I am adding it to the arraylist I have
itemsData.get(position).setIngredientValue(ingredientValue);
itemsData.get(position).setImageUrl(R.mipmap.remove_ing);
itemsData.get(position).setTag("Remove");
mAdapter.notifyDataSetChanged();
}
@Override
public void removeBtnClicked(int position, int itemCount) {
Log.d("listenerPosition:", String.valueOf(position));
itemsData.remove(position);
if(itemCount == 5){
itemsData.get(3).setImageUrl(R.mipmap.add_ing);
itemsData.get(3).setTag("Add3");
}
mAdapter.notifyDataSetChanged();
}
这很好地工作。当我的应用程序加载时,我看到一个 EditText 和一个 ImageButton。当我第一次单击 ImageButton 时,它会在我的第一个下方添加我的第二个 EditText 和第二个 ImageButton。
但是,当我第二次单击我的按钮时,问题就出现了。第三行被插入到顶部RecyclerView
而不是底部。我已经存在的第 1 行和第 2 行被下推(连同 EditText 的内容),我新添加的行进入回收器的顶部。
当我单击新插入的顶行上的“删除”按钮时,它变得更加奇怪。它删除了一行(如预期的那样)并清除了我所有的 EditTexts(为什么)。
如果有人可以看看这个并告诉我我在哪里犯了错误,我将不胜感激。如果需要,我可以提供更多我的代码。
解决方案
您指定该位置final
在 中,ViewHolder
因此您可以在处理程序中引用它onClick()
。由于该变量是,无论可能采取final
任何新位置,它都不会改变。ViewHolder
而不是final
变量,请尝试使用getAdapterPosition()
.
getAdapterPosition
int getAdapterPosition ()
返回此 ViewHolder 表示的项目的适配器位置。
这可能不是您的问题,但请尝试一下。
推荐阅读
- themes - Vaadin Flow 应用程序自动在明暗模式之间切换
- google-app-maker - 有没有人试过让这个签名板在 Google App Maker 中工作
- javascript - 如何更新 MongoDB 中字符串的子集?
- google-bigquery - BigQuery:优化查询以获得每月访问量最大的 5 个维基百科页面
- python - 处理命令行参数中的 unicode 字符
- reactjs - 用值预填充 React 表单
- flutter - 重复动画特定时间,例如 Flutter 20 次
- out-of-memory - 在 OutOfMemory 异常上终止 Spring Cloud 任务
- google-apps-script - 修改代码 - 将范围复制到另一个电子表格 Google 表格
- c# - 我可以在单个按钮上添加 2 个功能吗(Unity)