为啥滚动时 RecyclerView (在我的情况下)中 CardView 的内容会发生变化?

Posted

技术标签:

【中文标题】为啥滚动时 RecyclerView (在我的情况下)中 CardView 的内容会发生变化?【英文标题】:Why is the content of CardView inside a RecyclerView (in my case) changing when I scroll?为什么滚动时 RecyclerView (在我的情况下)中 CardView 的内容会发生变化? 【发布时间】:2020-11-10 05:39:52 【问题描述】:

我也有类似这个帖子"Cardview's data are changed while scrolling RecyclerView"的同样问题。

但是取出静态参数不起作用。

我正在做的事情的背景:

我在FlexboxLayoutCardView 中添加了几个按钮(CardViewRecyclerView 中)。正在动态添加按钮。

同样的事情发生在几个TextView,我在Buttons 之后添加到CardView

问题:

Buttons 和 TextViews 正在相乘,而我滚动。

滚动时正在交换不同CardViews 的上下文。

视频:https://sendvid.com/adugp8vh

我正在使用什么:

RecyclerView 在我的Fragments (ConstraintLayout) 之一中,我在其中定义了回收器适配器。

这是我的适配器

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> 
ArrayList<DataModel> dataSet = new ArrayList<DataModel>();
Context currentContext;

public class MyViewHolder extends RecyclerView.ViewHolder 

    public Button datumButton;
    public FlexboxLayout matchedWordsLayout;
    public LinearLayout textviewLayout;



    public MyViewHolder(View itemView) 
        super(itemView);
        this.datumButton = (Button) itemView.findViewById(R.id.datumButton);
        this.matchedWordsLayout = (FlexboxLayout) itemView.findViewById(R.id.matchedWordsLayout);
        this.textviewLayout = (LinearLayout) itemView.findViewById(R.id.textviewLayout);

    



public CustomAdapter(ArrayList<DataModel> data, Context currentContext) 
    this.dataSet = data;
    // currentContext not getting it from here



@NonNull
@Override
public CustomAdapter onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 

    View view =  LayoutInflater.from(parent.getContext())
            .inflate(R.layout.positive_result_card, parent, false);

    MyViewHolder myViewHolder = new MyViewHolder(view);
    this.currentContext = parent.getContext();
    return myViewHolder;



@RequiresApi(api = Build.VERSION_CODES.O)
//@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int listPosition) 
    Button DatumButton = holder.datumButton;
    FlexboxLayout MatchedWordsLayout = holder.matchedWordsLayout;
    LinearLayout TextviewLayout = holder.textviewLayout;

    //Modify the button for date
    ArrayList <String> TTMMYY = dataSet.get(listPosition).getDatum();
    String Datum = String.join(".", TTMMYY);
    DatumButton.setText(Datum);
    DatumButton.setTag(Datum);
  

  



    // add button for each word
    ArrayList <String>  ButtonNames = dataSet.get(listPosition).getButtonnames();

    for (String Buttonname : ButtonNames) 
        Button sampleButton = new Button(currentContext);
        sampleButton.setText(Buttonname);
        sampleButton.setTag(Datum); 

        MatchedWordsLayout.addView(sampleButton);
    

    
    ArrayList <String> textLines = dataSet.get(listPosition).getTextLines();
    

   
    for (String satzt : textLines)
        TextView sampleTextView = new TextView(currentContext);
        sampleTextView.setText(satzt);

        TextviewLayout.addView(sampleTextView);
    







@Override
public int getItemCount() 
    return dataSet.size();

  

我的文字可能有错误

【问题讨论】:

【参考方案1】:

您以编程方式在每个绑定上添加Views,但您永远不会删除它们,因此每个绑定只会添加更多(请记住ViewHolders 被重复使用,因此Buttons 和TextViews您上次添加的仍然存在)。要解决此问题,请在添加新子代之前从 ViewGroups 中删除所有子代:

    // Added: remove all the children before we add more
    MatchedWordsLayout.removeAllViews();

    for (String Buttonname : ButtonNames) 
        Button sampleButton = new Button(currentContext);
        sampleButton.setText(Buttonname);
        sampleButton.setTag(Datum); 

        MatchedWordsLayout.addView(sampleButton);
    

    
    ArrayList <String> textLines = dataSet.get(listPosition).getTextLines();
    
    // Added: remove all the children before we add more
    TextviewLayout.removeAllViews();

    for (String satzt : textLines)
        TextView sampleTextView = new TextView(currentContext);
        sampleTextView.setText(satzt);

        TextviewLayout.addView(sampleTextView);
    

【讨论】:

谢谢,我想经过两天的努力,它可以工作了。问题:我认为数据集的每个实例都是单独的,所以要为新卡添加的数据被设置为它的原始值?还有第二个问题,为什么它会在我滚动的时候发生? 滚动时会发生这种情况,因为当您将一个 ViewHolder 滚动出屏幕时,它会重新绑定并重新用于另一条数据。这种重新绑定发生在您通过滚动查看不同的数据片段时,或者如果您使用Adapter 上的notify... 方法之一显式触发重新绑定。

以上是关于为啥滚动时 RecyclerView (在我的情况下)中 CardView 的内容会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章

为啥直到在选项卡之间滚动才会显示 recyclerview 项目?

没有滚动时屏幕底部的 Recyclerview 页脚和滚动时位于列表末尾的 Recyclerview 页脚

为啥在recyclerview android中滚动后突出显示的项目丢失

为啥我的网站在我滚动时在 Chrome 中显示滞后?

RecyclerView 项目失去焦点

使用导航组件保存 RecyclerView 的滚动