RecyclerView每隔几项都是相同的-展开式项目 [英] RecyclerView every few items are the same - expandable item

查看:80
本文介绍了RecyclerView每隔几项都是相同的-展开式项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对recyclerView有问题.我正在使用此布局在recyclerView中展开cardView: https://github.com/AAkira/ExpandableLayout

I have a problem with recyclerView. I'm using this layout to expand cardView in recyclerView: https://github.com/AAkira/ExpandableLayout .

如果我单击某个项目以展开,然后向下滚动,则第7个元素也将展开.我该怎么做才能停止这种影响?我知道这是因为recyclerView会记住视图持有者的状态,并且onBindiewHolder方法中的mIsViewExpanded设置为每第7个项目为true.预先感谢您提供任何解决方案!

If I click on some item to expand and than scroll down every 7th element is also expanded. What can I do to stop that effect? I know that this is caused beacause recyclerView remembers state of view holder and mIsViewExpanded in method onBindiewHolder is set to true every 7th item. Thanks in advance for any solutions!

这是我的观看者的代码:

Here is code of my 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会根据mIsViewExpanded值而扩展或崩溃.

When I click on icon inside CardView expandableArea is expanding or collapsing depending on mIsViewExpanded value.

编辑. 适配器代码:

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

}

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

This is how I deal with it right now. In adapter class I have boolean array which lenght is the same as listData. On position corresponding to list item I keep value: true when expanded, false when collapsed. In the onBindViewHolder I check if position is expanded and if not I collapse it. It's not the ideal solution because during scroll items are collapsing and it doesn't look good.

推荐答案

RecyclerView不会创建新视图,而是在滚动(ScrappedViews)时重用现有视图.所以发生了什么事,当您扩展CardView并滚动时,由于CardView被重用,您将获得另一个扩展视图.

RecyclerView doesn't create new views instead it reuses the existing views when scrolling (ScrappedViews). So what is happening is when you expand a CardView and scroll, since the CardViews are reused you get another expanded view.

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

So simply collapse/expand the view in the onBindView() of your Adapter, for that you'll need to associate a state with each item in adapter's list.

要简单地在滚动过程中解决展开/折叠动画,请按setDuration(0)键,您可以展开/折叠而没有任何延迟或动画,从而获得流畅的滚动体验.

To resolve the expand/collapse animation during scrolling simply setDuration(0) which allows you to expand/collapse without any delay or animation for smoother scrolling experience.

这篇关于RecyclerView每隔几项都是相同的-展开式项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆