简体   繁体   English

RecyclerView的项目未正确显示

[英]Items of RecyclerView are not showing correctly

In my onBindViewHolder of my RecyclerView.Adapter<SearchAdapter.ViewHolder> when user clicks on cardview a button becomes visible. 在我的onBindViewHolder我的RecyclerView.Adapter<SearchAdapter.ViewHolder>当用户点击cardview按钮变得可见。 But when I'm scrolling recyclerview some other items buttons are shown as visible too. 但是当我滚动recyclerview时,其他一些项目按钮也显示为可见。 Why is this happening? 为什么会这样?

this is my code: 这是我的代码:

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
    viewHolder.card.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (viewHolder.content_layout.getVisibility() == View.VISIBLE) {
                viewHolder.content_layout.setVisibility(View.GONE);
                viewHolder.address.setMaxLines(2);
                viewHolder.attribute.setMaxLines(2);
            } else {
                viewHolder.content_layout.setVisibility(View.VISIBLE);
                viewHolder.address.setMaxLines(8);
                viewHolder.attribute.setMaxLines(8);
            }
        }
    });
    ...
}

Once you start scrolling down the list your views get recycled. 一旦开始向下滚动列表,您的视图就会被回收。 This means a previously inflated ViewHolder (some that gets created in onCreateViewHolder ) is reused. 这意味着重用以前膨胀的ViewHolder(在onCreateViewHolder创建的一些)。
So what you have to do is to remember the clicked positions (eg via a SparseBooleanArray ) and check in onBindViewHolder whether the view should be visible (previously clicked) or not. 所以你要做的就是记住点击的位置(例如通过SparseBooleanArray )并检查onBindViewHolder是否应该可见(先前点击过)。

You can find a basic usage example of the SparseBooleanArray in this StackOverflow post 您可以在此StackOverflow帖子中找到SparseBooleanArray的基本用法示例

The 'other' visible items buttons are the ones using the same viewholder that was modified in the callback. “其他”可见项按钮是使用在回调中修改的相同视图的按钮。 So because viewholders (and views) are recycled : 因为视图持有者(和视图)被回收:

  • They should only store information that can be retrieved each time the viewholder is bound to a position. 它们应该只存储每次将视图符号绑定到某个位置时可以检索的信息。

  • Anything that may be changed in the views state should be refreshed in onBindViewHolder() 应该在onBindViewHolder()刷新视图状态中可能更改的任何内容

In your case you should store the 'is selected' somewhere else and reset the visibility and maxlines in onBindViewHolder() (not only in the callback) 在你的情况下你应该在其他地方存储'被选中' 重置onBindViewHolder()的可见性和onBindViewHolder()不仅在回调中)

Good idea is to make a class object with all data you need for one item in recycler view, also add there one boolean isItemWasClicked and inside onBindViewHolder() check this boolean and make buttons visible or not. 好主意是在onBindViewHolder()视图中创建一个包含一个项目所需数据的类对象,同时在其中添加一个布尔值isItemWasClicked并在onBindViewHolder()内部检查此布尔值并使按钮可见或不可见。 For example: 例如:

public class OneItemOfList{
    int priceToDisplay;
    String name;
    String date;
    boolean wasClicked;
}

public class YourAdapter extends RecyclerView.Adapter<OneItemOfList.ViewHolder> {
ArrayList<OneItemOfList> items;
...
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
    viewHolder.view.setText(items.get(position).name);
    if (items.get(position).wasClicked)
        viewHolder.button.setVisible(View.VISIBLE);
    else
        viewHolder.button.setVisible(View.GONE);
    viewHolder.view2.setOnClickListener(...
        OnClick(...){
            items.get(position).wasClicked = !items.get(position).wasClicked;
        });
}
...
}

create an array for example Boolean array, and when each position clicked, set true in same position of array. 创建一个数组,例如布尔数组,当点击每个位置时,在数组的相同位置设置true。 and in onBindViewHolder check if that array[position] is true set that item visible if. 并在onBindViewHolder中检查该数组[position]是否为true,将该项设置为visible if。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM