RecyclerView正在复制项目

时间:2019-02-22 02:31:13

标签: android android-recyclerview notifydatasetchanged

滚动时我的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();

                }
            });
        }
    }
}

在下面的图像中,您可以看到单选按钮重复,并且所有行中都有一些额外的空格。我在这里和另一个论坛上都看到了很多与此有关的问题,但是我不清楚在哪里调用此更新数据集。

enter image description here

我不是一名高级Android开发人员,所以如果您能解释一下,这对我来说会更容易。

编辑1

清单类:

       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

适配器代码已更新

9 个答案:

答案 0 :(得分:5)

holder.setIsRecyclable(false)中使用onCreateViewHolder()

对我有用。

答案 1 :(得分:2)

将 holder.setIsRecyclable(false) 放在 onBindViewHolder() 中,如下例所示。

@Override
    public void onBindViewHolder(UsageStatVH holder, int position) {
        holder.bindTo(list.get(position));
        holder.setIsRecyclable(false);
    }

答案 2 :(得分:1)

我复制了您的问题。

holder.priceGroup.removeAllViews();上添加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;
    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);
    }
}

您每次都在不删除先前视图的情况下添加到视图。

答案 3 :(得分:0)

这是因为您要将列表设置为适配器的三次,

目前我无法编写完整的代码,但是将其替换为您的代码即可。

尝试此代码,

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

答案 4 :(得分:0)

请在ChecklistAdapter中覆盖以下方法

@Override
public long getItemId(int position) {
    return position;
}

然后在您的onCreate()中添加:

recyclerViewAdapter.setHasStableIds(true);

答案 5 :(得分:0)

代替

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

希望这会对您有所帮助。

答案 6 :(得分:0)

您必须在活动中将HasStableIds(true)设置为适配器。

,并且在Adapter类中,必须设置以下方法。它可能会帮助您。这对我来说是工作。

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

您想要这样吗?

enter image description here

答案 7 :(得分:0)

修改清单...

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

我认为这可以解决您的问题。 快乐编码

答案 8 :(得分:0)

您只需在插入list.clear();之前先调用RecyclerViewAdapter。然后再致电adapter.notifyDatasetChange()