RecyclerView 正在复制项目
RecyclerView is duplicating items
我的 recyclerview 在滚动时正在复制项目,我已经在调用 adapter.notifyDataSetChanged()
。
所以,可能我在错误的地方调用了数据集更新,但我找不到它是如何工作的。
这是一些代码:
RecyclerView packageRecyclerView;
Intent intent;
ChecklistAdapter recyclerViewAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checklist);
intent = getIntent();
size = intent.getIntExtra("size", 0);
Log.d(TAG, "onCreate - Qtd Questões: " + size);
packageRecyclerView = findViewById(R.id.package_lst);
LinearLayoutManager recyclerLayoutManager = new LinearLayoutManager(this);
packageRecyclerView.setLayoutManager(recyclerLayoutManager);
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(packageRecyclerView.getContext(),
recyclerLayoutManager.getOrientation());
packageRecyclerView.addItemDecoration(dividerItemDecoration);
List<Checklist> modelList = new ArrayList<>();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
modelList = getPackages();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
// recyclerViewAdapter = new ChecklistAdapter(getPackages(),this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
}
private List<Checklist> getPackages() {
List<Checklist> modelList = new ArrayList<>();
Log.d(TAG, "getPackages: " + size);
for (int i=0; i<size;i++) {
List<String> priceList = new ArrayList<>();
priceList.add("Sim");
priceList.add("Não");
priceList.add("Não se Aplica");
modelList.add(new Checklist(intent.getStringExtra("q"+i), priceList));
}
recyclerViewAdapter.notifyDataSetChanged();
return modelList;
}
这是我的适配器:
public class ChecklistAdapter extends
RecyclerView.Adapter<ChecklistAdapter.ViewHolder> {
private List<Checklist> packageList;
private Context context;
public ChecklistAdapter(List<Checklist> packageListIn
, Context ctx) {
packageList = packageListIn;
context = ctx;
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
@Override
public long getItemId(int position) {
return super.getItemId(position);
}
@Override
public ChecklistAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.rv_checklistlines, parent, false);
ChecklistAdapter.ViewHolder viewHolder =
new ChecklistAdapter.ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
}
@Override
public void onBindViewHolder(ChecklistAdapter.ViewHolder holder,
int position) {
Checklist packageModel = packageList.get(position);
holder.packageName.setText(packageModel.getTitle());
int id = (position+1)*100;
for(String price : packageModel.getQuestions()){
RadioButton rb = new RadioButton(ChecklistAdapter.this.context);
rb.setId(id++);
rb.setText(price);
holder.priceGroup.addView(rb);
}
}
@Override
public int getItemCount() {
return packageList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView packageName;
public RadioGroup priceGroup;
public ViewHolder(View view) {
super(view);
packageName = view.findViewById(R.id.package_name);
priceGroup = view.findViewById(R.id.price_grp);
priceGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
Toast.makeText(ChecklistAdapter.this.context,
"Radio button clicked " + radioGroup.getCheckedRadioButtonId(),
Toast.LENGTH_SHORT).show();
}
});
}
}
}
在下图中,您可以看到单选按钮是重复的,并且所有行中都有一些额外的空白 space。我在这里和其他论坛上看到了很多关于这个的问题,但我不清楚在哪里调用这个更新数据集。
我不是高级 Android 开发人员,所以如果你能解释一下,我会更容易。
编辑 1
清单class:
import java.util.List;
public class Checklist {
String title;
List<String> questions;
public Checklist(String title, List<String> questions) {
this.title = title;
this.questions = questions;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<String> getQuestions() {
return questions;
}
public void setQuestions(List<String> questions) {
this.questions = questions;
}
编辑 2
适配器代码已更新
因为你设置了三次适配器列表,
目前我无法编写完整的代码,但在您的代码中替换此块它会起作用。
试试这个代码,
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(packageRecyclerView.getContext(), recyclerLayoutManager.getOrientation());
packageRecyclerView.addItemDecoration(dividerItemDecoration);
List<Checklist> modelList = new ArrayList<>();
modelList = getPackages(); recyclerViewAdapter = new ChecklistAdapter(modelList,this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
同时从您的 getPackages() 函数中删除以下行。
recyclerViewAdapter.notifyDataSetChanged();
请覆盖 ChecklistAdapter 中的以下方法
@Override
public long getItemId(int position) {
return position;
}
并在您的 onCreate() 中添加:
recyclerViewAdapter.setHasStableIds(true);
而不是
List<Checklist> modelList = new ArrayList<>();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
modelList = getPackages();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
这样使用
recyclerViewAdapter = new ChecklistAdapter(getPackages(),this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
并修改您的 getPackages 方法,例如
private List<Checklist> getPackages() {
List<Checklist> modelList = new ArrayList<>();
Log.d(TAG, "getPackages: " + size);
for (int i=0; i<size;i++) {
List<String> priceList = new ArrayList<>();
priceList.add("Sim");
priceList.add("Não");
priceList.add("Não se Aplica");
modelList.add(new Checklist(intent.getStringExtra("q"+i), priceList));
}
return modelList;
}
希望对您有所帮助。
您必须在 activity 中为您的适配器设置 HasStableIds(true)。
并且在您的适配器中 class 您必须设置以下方法。它可能对你有帮助。这对我有用。
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
你想要这样吗?
修改您的清单...
public class Checklist {
String title;
List<String> questions;
boolean isRadioButtonAdded;
public Checklist(String title, List<String> questions) {
this.title = title;
this.questions = questions;
}
public boolean getIsAdded(){
return isRadioButtonAdded;
}
public void setIsAdded(boolean isAdded){
this.isRadioButtonAdded = isAdded;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<String> getQuestions() {
return questions;
}
public void setQuestions(List<String> questions) {
this.questions = questions;
}
并修改你的onBindViewHolder
@Override
public void onBindViewHolder(ChecklistAdapter.ViewHolder holder,
int position) {
Checklist packageModel = packageList.get(position);
holder.packageName.setText(packageModel.getTitle());
int id = (position+1)*100;
if(!packageModel.getIsAdded){
for(String price : packageModel.getQuestions()){
RadioButton rb = new RadioButton(ChecklistAdapter.this.context);
rb.setId(id++);
rb.setText(price);
holder.priceGroup.addView(rb);
packageModel.setIsAdded(true)
}
}
}
我复制了你的问题。
在 onBindViewHolder
上添加 holder.priceGroup.removeAllViews();
将修复它。像这样:
@Override
public void onBindViewHolder(ChecklistAdapter.ViewHolder holder,
int position) {
Checklist packageModel = packageList.get(position);
holder.packageName.setText(packageModel.getTitle());
int id = (position+1)*100;
holder.priceGroup.removeAllViews();
for(String price : packageModel.getQuestions()){
RadioButton rb = new RadioButton(ChecklistAdapter.this.context);
rb.setId(id++);
rb.setText(price);
holder.priceGroup.addView(rb);
}
}
您每次都在添加视图而没有删除以前的视图。
在onCreateViewHolder()
中使用holder.setIsRecyclable(false)
对我有用。
您只需在插入 RecyclerViewAdapter
之前调用 list.clear();
。然后接电话接电话adapter.notifyDatasetChange()
将 holder.setIsRecyclable(false) 放入 onBindViewHolder() 中,如下例所示。
@Override
public void onBindViewHolder(UsageStatVH holder, int position) {
holder.bindTo(list.get(position));
holder.setIsRecyclable(false);
}
我的 recyclerview 在滚动时正在复制项目,我已经在调用 adapter.notifyDataSetChanged()
。
所以,可能我在错误的地方调用了数据集更新,但我找不到它是如何工作的。
这是一些代码:
RecyclerView packageRecyclerView;
Intent intent;
ChecklistAdapter recyclerViewAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checklist);
intent = getIntent();
size = intent.getIntExtra("size", 0);
Log.d(TAG, "onCreate - Qtd Questões: " + size);
packageRecyclerView = findViewById(R.id.package_lst);
LinearLayoutManager recyclerLayoutManager = new LinearLayoutManager(this);
packageRecyclerView.setLayoutManager(recyclerLayoutManager);
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(packageRecyclerView.getContext(),
recyclerLayoutManager.getOrientation());
packageRecyclerView.addItemDecoration(dividerItemDecoration);
List<Checklist> modelList = new ArrayList<>();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
modelList = getPackages();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
// recyclerViewAdapter = new ChecklistAdapter(getPackages(),this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
}
private List<Checklist> getPackages() {
List<Checklist> modelList = new ArrayList<>();
Log.d(TAG, "getPackages: " + size);
for (int i=0; i<size;i++) {
List<String> priceList = new ArrayList<>();
priceList.add("Sim");
priceList.add("Não");
priceList.add("Não se Aplica");
modelList.add(new Checklist(intent.getStringExtra("q"+i), priceList));
}
recyclerViewAdapter.notifyDataSetChanged();
return modelList;
}
这是我的适配器:
public class ChecklistAdapter extends
RecyclerView.Adapter<ChecklistAdapter.ViewHolder> {
private List<Checklist> packageList;
private Context context;
public ChecklistAdapter(List<Checklist> packageListIn
, Context ctx) {
packageList = packageListIn;
context = ctx;
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
@Override
public long getItemId(int position) {
return super.getItemId(position);
}
@Override
public ChecklistAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.rv_checklistlines, parent, false);
ChecklistAdapter.ViewHolder viewHolder =
new ChecklistAdapter.ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
}
@Override
public void onBindViewHolder(ChecklistAdapter.ViewHolder holder,
int position) {
Checklist packageModel = packageList.get(position);
holder.packageName.setText(packageModel.getTitle());
int id = (position+1)*100;
for(String price : packageModel.getQuestions()){
RadioButton rb = new RadioButton(ChecklistAdapter.this.context);
rb.setId(id++);
rb.setText(price);
holder.priceGroup.addView(rb);
}
}
@Override
public int getItemCount() {
return packageList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView packageName;
public RadioGroup priceGroup;
public ViewHolder(View view) {
super(view);
packageName = view.findViewById(R.id.package_name);
priceGroup = view.findViewById(R.id.price_grp);
priceGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
Toast.makeText(ChecklistAdapter.this.context,
"Radio button clicked " + radioGroup.getCheckedRadioButtonId(),
Toast.LENGTH_SHORT).show();
}
});
}
}
}
在下图中,您可以看到单选按钮是重复的,并且所有行中都有一些额外的空白 space。我在这里和其他论坛上看到了很多关于这个的问题,但我不清楚在哪里调用这个更新数据集。
我不是高级 Android 开发人员,所以如果你能解释一下,我会更容易。
编辑 1
清单class:
import java.util.List;
public class Checklist {
String title;
List<String> questions;
public Checklist(String title, List<String> questions) {
this.title = title;
this.questions = questions;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<String> getQuestions() {
return questions;
}
public void setQuestions(List<String> questions) {
this.questions = questions;
}
编辑 2
适配器代码已更新
因为你设置了三次适配器列表,
目前我无法编写完整的代码,但在您的代码中替换此块它会起作用。
试试这个代码,
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(packageRecyclerView.getContext(), recyclerLayoutManager.getOrientation());
packageRecyclerView.addItemDecoration(dividerItemDecoration);
List<Checklist> modelList = new ArrayList<>();
modelList = getPackages(); recyclerViewAdapter = new ChecklistAdapter(modelList,this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
同时从您的 getPackages() 函数中删除以下行。
recyclerViewAdapter.notifyDataSetChanged();
请覆盖 ChecklistAdapter 中的以下方法
@Override
public long getItemId(int position) {
return position;
}
并在您的 onCreate() 中添加:
recyclerViewAdapter.setHasStableIds(true);
而不是
List<Checklist> modelList = new ArrayList<>();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
modelList = getPackages();
recyclerViewAdapter = new ChecklistAdapter(modelList,this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
这样使用
recyclerViewAdapter = new ChecklistAdapter(getPackages(),this);
packageRecyclerView.setAdapter(recyclerViewAdapter);
并修改您的 getPackages 方法,例如
private List<Checklist> getPackages() {
List<Checklist> modelList = new ArrayList<>();
Log.d(TAG, "getPackages: " + size);
for (int i=0; i<size;i++) {
List<String> priceList = new ArrayList<>();
priceList.add("Sim");
priceList.add("Não");
priceList.add("Não se Aplica");
modelList.add(new Checklist(intent.getStringExtra("q"+i), priceList));
}
return modelList;
}
希望对您有所帮助。
您必须在 activity 中为您的适配器设置 HasStableIds(true)。
并且在您的适配器中 class 您必须设置以下方法。它可能对你有帮助。这对我有用。
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(hasStableIds);
}
你想要这样吗?
修改您的清单...
public class Checklist {
String title;
List<String> questions;
boolean isRadioButtonAdded;
public Checklist(String title, List<String> questions) {
this.title = title;
this.questions = questions;
}
public boolean getIsAdded(){
return isRadioButtonAdded;
}
public void setIsAdded(boolean isAdded){
this.isRadioButtonAdded = isAdded;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<String> getQuestions() {
return questions;
}
public void setQuestions(List<String> questions) {
this.questions = questions;
}
并修改你的onBindViewHolder
@Override
public void onBindViewHolder(ChecklistAdapter.ViewHolder holder,
int position) {
Checklist packageModel = packageList.get(position);
holder.packageName.setText(packageModel.getTitle());
int id = (position+1)*100;
if(!packageModel.getIsAdded){
for(String price : packageModel.getQuestions()){
RadioButton rb = new RadioButton(ChecklistAdapter.this.context);
rb.setId(id++);
rb.setText(price);
holder.priceGroup.addView(rb);
packageModel.setIsAdded(true)
}
}
}
我复制了你的问题。
在 onBindViewHolder
上添加 holder.priceGroup.removeAllViews();
将修复它。像这样:
@Override
public void onBindViewHolder(ChecklistAdapter.ViewHolder holder,
int position) {
Checklist packageModel = packageList.get(position);
holder.packageName.setText(packageModel.getTitle());
int id = (position+1)*100;
holder.priceGroup.removeAllViews();
for(String price : packageModel.getQuestions()){
RadioButton rb = new RadioButton(ChecklistAdapter.this.context);
rb.setId(id++);
rb.setText(price);
holder.priceGroup.addView(rb);
}
}
您每次都在添加视图而没有删除以前的视图。
在onCreateViewHolder()
holder.setIsRecyclable(false)
对我有用。
您只需在插入 RecyclerViewAdapter
之前调用 list.clear();
。然后接电话接电话adapter.notifyDatasetChange()
将 holder.setIsRecyclable(false) 放入 onBindViewHolder() 中,如下例所示。
@Override
public void onBindViewHolder(UsageStatVH holder, int position) {
holder.bindTo(list.get(position));
holder.setIsRecyclable(false);
}