RecyclerView设置要回收的视图

时间:2015-11-05 10:37:49

标签: android android-recyclerview

在我的应用中,我正在实施Recyclerview。根据我为Recyclerview上显示的数据设置的选项,此Recyclerview的数据集将具有不同的大小。

我对Recyclerview采取的一项行动是在点击完成后“展开”某个项目,并在其中显示更多选项。当按下这个“扩展”项目时,我执行“关闭”它的操作。此外,任何时候最多只能在“扩展”项目上。

事情就是我明白,Recyclerview会在看不到它们的行视图时再循环以提高性能。但是,因为我试图一次只有一个“扩展”项目,这种回收会使它变得非常混乱。

现在发生的事情是,当我“展开”时,说出与我的数据集的位置1相关的项目,如下图所示。

item for position 1 "expanded"

当我向下滚动时,我会看到此项目的行视图随机被回收,因为我将看到这个“扩展”视图,我没有设置为“展开”,如图所示下方。

this happened for me only scrolling down through my recyclerview

当然,当这种情况发生时,当我滚动回到我选择“扩展”的项目时,它会像您预期的那样“关闭”。

所以我一直在想我可以通过将可能的视图数设置为80%的数据集大小来减少发生此问题的可能性,同时仍然减少,但可以享受一些改进的性能来解决这个问题。 / p>

我想到的另一个解决方案是禁止这个“扩展”视图被回收用于其他视图,当这个“扩展”项目的位置进入屏幕时,它会受到这个特定视图的限制。在看到Recyclerview有“废料”和“回收”的概念后,我想到了这个解决方案,但我不确定这种方法是否可行,因为我认为我只是模糊地理解了Recyclerview的这一面。

话虽这么说,我的问题是我有办法设置回收视图的回收数量吗?或者甚至更好,有一个视图被回收用于“扩展”项目以外的项目吗?

提前致谢。

编辑:

这是我的(我知道这很麻烦,对不起......)我的适配器的代码:

public class DrinkMenuItem extends RecyclerView.Adapter<DrinkMenuItem.ViewHolder> {
    private Context context;
    private ViewGroup parent;
    private ArrayList<Drink> menu;
    private ArrayList<DrinkSelected> selected;
    private DrinkMenuBasketItem selectedAdapter;

    public int expanded = -1;
    public boolean expandedVisible = false;

    private DrinkMenuDropdownItem dropdownAdapter;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public RelativeLayout layout;
        public TextView name, price;
        public ListView dropdown;
        public RelativeLayout basket;
        public boolean tabbed = false;

        public ViewHolder(View itemView) {
            super(itemView);
            layout = (RelativeLayout)itemView.findViewById(R.id.drink_menu_layout);
            name = (TextView)itemView.findViewById(R.id.drink_menu_name);
            price = (TextView)itemView.findViewById(R.id.drink_menu_price);
            dropdown = (ListView)itemView.findViewById(R.id.drink_menu_dropdown_list);
            basket = (RelativeLayout)itemView.findViewById(R.id.drink_menu_basket_button);
        }
    }

    public DrinkMenuItem(Context context, ArrayList<Drink> menu, ArrayList<DrinkSelected> selected, DrinkMenuBasketItem selectedAdapter) {
        this.context = context;
        this.menu = menu;
        this.selected = selected;
        this.selectedAdapter = selectedAdapter;
        this.dropdownAdapter = null;
    }

    public void updateDropdown(int requestedOption, int responsedOptionitem) {
        dropdownAdapter.updateSelectedOption(requestedOption, responsedOptionitem);
        notifyDataSetChanged();
    }

    // Create new views (invoked by the layout manager)
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        this.parent = parent;
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_drink_menu, parent, false);

        return new ViewHolder(itemView);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Drink d = menu.get(position);
        holder.name.setText(d.getName());
        holder.price.setText(d.getPrice() + d.totalAdditionalPrice() + "원");

        if(position == expanded) {
            //delete dropdown
            holder.dropdown.setAdapter(null);
            menu.get(position).returnToUnselected();
            holder.price.setText(menu.get(position).getPrice() + "원");
            setListViewHeight(holder.dropdown);

            //reset dropdown-related stuff
            holder.tabbed = false;
            holder.basket.setVisibility(View.GONE);
        }

        setOnClickEvent(holder, position, parent);
    }

    private void setOnClickEvent(final ViewHolder holder, final int position, final ViewGroup parent) {
        holder.layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!holder.tabbed) {
                    //close dropdown of expanded view
                    if(expanded != -1) notifyItemChanged(expanded);
                    //make dropdown
                    dropdownAdapter = new DrinkMenuDropdownItem(context, menu, position, holder.price);
                    holder.dropdown.setAdapter(dropdownAdapter);
                    setListViewHeight(holder.dropdown);
                    //set dropdown-related stuff
                    holder.tabbed = true;
                    holder.basket.setVisibility(View.VISIBLE);
                    expanded = position;
                    expandedVisible = true;

                   ((RecyclerView) parent).smoothScrollToPosition(position);
                } else {
                    //delete dropdown
                    holder.dropdown.setAdapter(null);
                    menu.get(position).returnToUnselected();
                    holder.price.setText(menu.get(position).getPrice() + "원");
                    setListViewHeight(holder.dropdown);
                    expanded = -1;
                    expandedVisible = false;

                    //reset dropdown-related stuff
                    holder.tabbed = false;
                    holder.basket.setVisibility(View.GONE);
                }
            }
        });
        ...
    }
}

1 个答案:

答案 0 :(得分:1)

我的项目中存在完全相同的问题。我没有用recyclerView成功解决它。但解决方案将是以下之一:

  1. 创建expandableListView而不是recyclerView,一切都会很好。
  2. 创建ScrollView,并将LinearLayoutandroid:orientation="vertical"放在一起。然后,创建一个循环并插入所有自定义视图,并设置要在其中展开的单击侦听器。
  3. 使用可扩展的RecyclerView库,如下所示: https://github.com/h6ah4i/android-advancedrecyclerview https://github.com/bignerdranch/expandable-recycler-view