Android RecyclerView每隔几项是相同的-可扩展项

Android RecyclerView每隔几项是相同的-可扩展项,android,android-recyclerview,expandablelistview,Android,Android Recyclerview,Expandablelistview,我对recyclerView有问题。我正在使用此布局在recyclerView中展开cardView: 如果我点击某个项目展开,然后向下滚动,则每第7个元素也会展开。我能做些什么来阻止这种影响?我知道这是因为recyclerView记住了视图持有者的状态,而方法onBindiewHolder中的mIsViewExpanded每隔7项就设置为true。提前感谢您提供的任何解决方案 以下是我的viewholder的代码: class EventsViewHolder extends Recycler

我对recyclerView有问题。我正在使用此布局在recyclerView中展开cardView:

如果我点击某个项目展开,然后向下滚动,则每第7个元素也会展开。我能做些什么来阻止这种影响?我知道这是因为recyclerView记住了视图持有者的状态,而方法onBindiewHolder中的mIsViewExpanded每隔7项就设置为true。提前感谢您提供的任何解决方案

以下是我的viewholder的代码:

class EventsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    private ImageView edit, cancel, expandIcon;

    private ExpandableLayout expandableArea;
    private boolean mIsViewExpanded = false;

    public EventsViewHolder(View itemView) {
        super(itemView);
        expandIcon = (ImageView) itemView.findViewById(R.id.card_item_expand_icon);
        expandIcon.setOnClickListener(this);
        //divider = (View) itemView.findViewById(R.id.event_card_divider);
    }

    private void collapseArea(){
        expandableArea.collapse();
        edit.setVisibility(View.GONE);
        cancel.setVisibility(View.GONE);
        mIsViewExpanded = false;
        expandIcon.setImageResource(R.drawable.vector_drawable_ic_expand_more_black___px);
    }

    private void expandArea(){
        expandableArea.expand();
        edit.setVisibility(View.VISIBLE);
        cancel.setVisibility(View.VISIBLE);
        mIsViewExpanded = true;
        expandIcon.setImageResource(R.drawable.vector_drawable_ic_expand_less_black___px);
    }

    @Override
    public void onClick(View view) {
        if(mIsViewExpanded){
            collapseArea();
            isItemExpanded[getAdapterPosition()] = false;
        }
        else {
            expandArea();
            isItemExpanded[getAdapterPosition()] = true;
        }
    }
}
当我点击CardView expandableArea内的图标时,根据MisviewExpandableValue,该区域正在展开或折叠

编辑。 适配器代码:

public class EventsRecyclerViewAdapter extends RecyclerView.Adapter<EventsRecyclerViewAdapter.EventsViewHolder> implements PopupMenu.OnMenuItemClickListener, PopupMenu.OnDismissListener {

public interface EventsRecyclerViewAdapterInterface {
    public void emptyAdapter();

    public void itemDeleted(int id);
}

private List<Event> listData = new ArrayList<>();
private LayoutInflater inflater;
private MainActivity context;
private View view;
private int positionToCancel;

private boolean[] isItemExpanded;

private EventsRecyclerViewAdapterInterface deleteListener;

@Override
public boolean onMenuItemClick(MenuItem menuItem) {
    removeItem(positionToCancel);
    return true;
}

@Override
public void onDismiss(PopupMenu menu) {
    menu.dismiss();
}


public EventsRecyclerViewAdapter(Activity context, EventsRecyclerViewAdapterInterface deleteListener) {
    this.inflater = LayoutInflater.from(context);
    this.context = (MainActivity) context;
    this.deleteListener = deleteListener;
}

@Override
public EventsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    view = inflater.inflate(R.layout.item_event_card, parent, false);
    return new EventsViewHolder(view);
}

@Override
public void onBindViewHolder(EventsViewHolder holder, int position) {
    Event item = listData.get(position);

    if(!isItemExpanded[position]){
        if(holder.mIsViewExpanded){
            holder.collapseArea();
        }
    }
    else {
        holder.expandArea();
    }

    holder.title.setText(item.getName());
    holder.place.setText(item.getLocation());

    DateTimeFormatter formatter = DateTimeFormat.forPattern(StaticValues.DATE_TIME_PATTERN_FOR_VIEW);
    holder.time.setText(formatter.print(item.getDate()));

    holder.edit.setOnClickListener(view1 -> takeDetailsEvent(item));
    holder.cancel.setOnClickListener(view1 -> {
        positionToCancel = position;

        MyPopupMenu popup = new MyPopupMenu(view1.getContext(), view1, context);
        popup.inflate(R.menu.event_delete_menu);
        popup.setOnMenuItemClickListener(this);
        popup.setOnDismissListener(this);
        popup.show();
    });

    holder.container.setOnClickListener(view1 -> {
        Intent intent = new Intent(view1.getContext(), EventDetailsActivity.class);
        intent.putExtra("eventId", item.getApiId());
        view1.getContext().startActivity(intent);
    });
}

private void removeItem(int position) {
    deleteListener.itemDeleted(listData.get(position).getApiId());
    listData.remove(position);
    notifyDataSetChanged();

    if (getItemCount() == 0) {
        deleteListener.emptyAdapter();
    }
}

private void takeDetailsEvent(Event event) {
    Intent intent = new Intent(view.getContext(), CreateEventActivity.class);
    intent.putExtra("id", event.getApiId());
    view.getContext().startActivity(intent);
}

public void setListData(List<Event> eventList) {
    listData = eventList;
    isItemExpanded = new boolean[listData.size()];
    notifyDataSetChanged();
}

@Override
public int getItemCount() {
    return listData.size();
}
公共类事件RecycleServiceAdapter扩展了RecycleView。适配器实现了PopupMenu.OnMenuItemClickListener、PopupMenu.OnDismissListener{
公共接口事件RecycleServiceAdapterInterface{
public void emptyAdapter();
已删除公共无效项(int id);
}
private List listData=new ArrayList();
私人充气机;
私人活动语境;
私人视野;
私人内部职位取消;
私有布尔[]扩展;
私有事件RecycleServiceAdapterInterface deleteListener;
@凌驾
公共布尔onMenuItemClick(MenuItem MenuItem){
removeItem(位置取消);
返回true;
}
@凌驾
public void onDismiss(弹出菜单){
menu.discouse();
}
公共事件RecycleServiceAdapter(活动上下文,事件RecycleServiceAdapterInterface deleteListener){
this.inflater=layoutiner.from(上下文);
this.context=(MainActivity)context;
this.deleteListener=deleteListener;
}
@凌驾
公共事件ViewHolder onCreateViewHolder(视图组父级,int-viewType){
视图=充气机。充气(R.layout.item\u event\u card,父级,false);
返回新事件查看文件夹(视图);
}
@凌驾
BindViewHolder上的公共无效(EventsViewHolder,int位置){
事件项=listData.get(位置);
如果(!isItemExpanded[位置]){
如果(保持架。错误视图展开){
支架。卡环耳a();
}
}
否则{
支架。展开区域();
}
holder.title.setText(item.getName());
holder.place.setText(item.getLocation());
DateTimeFormatter formatter=DateTimeFormat.forPattern(StaticValues.DATE\u TIME\u PATTERN\u用于视图);
holder.time.setText(formatter.print(item.getDate());
holder.edit.setOnClickListener(view1->takeDetailsEvent(项目));
holder.cancel.setOnClickListener(视图1->{
positionToCancel=位置;
MyPopupMenu popup=新建MyPopupMenu(view1.getContext(),view1,context);
弹出。充气(右菜单。事件\删除\菜单);
popup.setOnMenuItemClickListener(这个);
popup.setOnDismissListener(此);
popup.show();
});
holder.container.setOnClickListener(视图1->{
Intent Intent=new Intent(view1.getContext(),EventDetailsActivity.class);
intent.putExtra(“eventId”,item.getapid());
view1.getContext().startActivity(intent);
});
}
私有无效删除项(内部位置){
deleteListener.itemDeleted(listData.get(position.getapid());
listData.remove(位置);
notifyDataSetChanged();
如果(getItemCount()==0){
deleteListener.emptyAdapter();
}
}
私有无效takeDetailsEvent(事件){
Intent Intent=new Intent(view.getContext(),CreateEventActivity.class);
intent.putExtra(“id”,event.getapid());
view.getContext().startActivity(intent);
}
public void setListData(列表事件列表){
listData=事件列表;
isItemExpanded=新布尔值[listData.size()];
notifyDataSetChanged();
}
@凌驾
public int getItemCount(){
返回listData.size();
}
}


我现在就是这样处理的。在适配器类中,我有一个长度与listData相同的布尔数组。在列表项对应的位置上,我保留值:展开时为true,折叠时为false。在onBindViewHolder中,我检查位置是否已展开,如果未展开,则将其折叠。这不是理想的解决方案,因为在滚动过程中,项目正在折叠,看起来不太好

RecyclerView
不会创建新视图,而是在滚动时重用现有视图(
报废视图
)。因此,当您展开一个
CardView
并滚动时,会发生什么情况呢?因为
CardView
s被重用,所以您会得到另一个展开的视图

因此,只需在
适配器的
onBindView()
中折叠/展开视图,您需要将状态与适配器列表中的每个项目关联起来


要解决滚动过程中的展开/折叠动画,只需
setDuration(0)
,它允许您在没有任何延迟的情况下展开/折叠动画,以获得更平滑的滚动体验。

这是recyclerView的预期行为。RecyclerView回收不在视图中的项目。如果您不希望您的物品被回收,请使用holder.setIsRecyclable(false);在适配器的onBindViewHolder()方法中

holder.setIsRecyclable(false);

在适配器中重写这两个方法

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

@Override
public int getItemViewType(int position) {
return position;
} 

Reference=

适配器类在哪里?在onBindViewHolder中,在适配器中,可以对要绑定到的ViewHolder进行标准折叠。这样,所有新视图都会折叠。这些项目都是循环视图,因此,每当您滚动某个特定项目时,该操作就会重复到列表中的其他项目。您可以使用(.setTag())存储项的操作,并使用(.getTag())重新设置它。然后它只是一个例子(if item.getTag()==1——Expand else Dont Expand)检查SO关于设置和获取适配器项的标记set
expandableView.setDuration(0)
,然后折叠/展开视图,然后重置持续时间。您仍然可以使用@Tasos的解决方案获得相同的扩展/折叠行为。这只是让自己保持
isItemExpanded[]
的一个解决方法。是的,我知道RecyclerView使用的是废弃视图,这就是为什么我问我可以用它做什么。我试图挽救ev的状态