【问题标题】:How to keep track of the selected items in a RecyclerView in Android?如何在 Android 的 RecyclerView 中跟踪所选项目?
【发布时间】:2015-07-15 10:38:05
【问题描述】:

如何使用RecyclerView 实现一致的项目选择?我明白RecyclerView 回收旧观点的全部想法,什么不是。我的问题是我有一个项目列表,每个项目上都有一个图标,当单击一个项目时,图标会改变颜色。我设法实现了所有这些,但我只是意识到,当我向下滚动列表时,其他项目的图标也发生了变化,当我滚动回我点击的项目时,图标不再在“点击颜色”。

有人知道如何跟踪所选项目吗?我一直看到一个名为 SparseBooleanArray 的东西,但我不知道如何实现它。

这是我的适配器代码:

public class TableRVAdapter extends RecyclerView.Adapter<TableRVAdapter.TableHolder> {

    List<Tables> tableList;
    private SparseBooleanArray selectedItems;

    public TableRVAdapter(List<Tables> tableList)
    {
        this.tableList = tableList;
        selectedItems = new SparseBooleanArray();
       // setHasStableIds(true);
    }
    class TableHolder extends RecyclerView.ViewHolder
    {
        TextView tableTV;
        CardView tableCV;
        View circle;
        View parentView;
        TableHolder(final View itemView)
        {
            super(itemView);
            tableTV = (TextView)itemView.findViewById(R.id.tableTV);
            tableCV = (CardView)itemView.findViewById(R.id.tableCV);
            circle = itemView.findViewById(R.id.statusCircle);
            itemView.setClickable(true);
            parentView = itemView;

            tableCV.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                     circle.setBackgroundResource(R.drawable.circle);

                }
            });
        }
        /*
        @Override
        public void onClick(View view) {
            if (selectedItems.get(getAdapterPosition(), false)) {
                tableCV.setSelected(false);
                circle.setBackgroundResource(R.drawable.circle2);
            }
            else {
                selectedItems.put(getAdapterPosition(), true);
                tableCV.setSelected(true);
                circle.setBackgroundResource(R.drawable.circle);
            }

        }*/
    }

    @Override
    public TableHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.table_item,parent,false);
        TableHolder tableHolder = new TableHolder(view);
        return tableHolder;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView)
    {
        super.onAttachedToRecyclerView(recyclerView);
    }


    @Override
    public void onBindViewHolder(TableHolder holder, int position) {
        holder.tableTV.setText(tableList.get(position).getTableNumber());

    }

    /**
     * Returns the total number of items in the data set hold by the adapter.
     *
     * @return The total number of items in this adapter.
     */
    @Override
    public int getItemCount() {
        return tableList.size();
    }

}

【问题讨论】:

    标签: java android android-recyclerview


    【解决方案1】:

    我知道这个问题已经得到解答,但有人可能会发现这个答案有用且容易。

    在回收站视图中有一个有用的方法是onViewRecycled

    这可以帮助您摆脱按下状态。当在 recycler 视图中处理图像/drawable 时,当某些元素不使用 drawable 时,将显示预览 recycler 视图的绘制图像,并且它会使所有数据看起来都错误,就像您使用所选视图时发生的一样。

    要以更简单的方式实现此目的,您可以使用此方法清除绘制的图像以重置其值。

    例如,您将所选元素的背景标记为绿色,并且您的某些视图包含图像(注意:只有 一些 元素),而不是使用此方法像这样:

    @Override
            public void onViewRecycled(MyViewHolder holder) {
                super.onViewRecycled(holder);
    
                // Set ImageView's Drawable as transperent
                holder.myImageView.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), android.R.color.transparent));
    
                // Set background color as transperent
                holder.bgContainer.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), android.R.color.transparent));
    
            }
    

    现在您可以管理具有所选元素的 ID/位置的整数 ArrayList(在回收站视图的项目上使用 onClick 方法)。

    使用onBindViewHolder(MyViewHolder myViewHolder, int position),您可以正常填充数据。对于设置背景,您可以简单地检查 id/位置是否在 ArrayList 中(如果 true,请将背景颜色设置为绿色 else 保持原样。如由 onViewRecylcer 方法管理,即使没有选中也不会影响其他绿色背景的滚动项)。

    希望它能对某人有所帮助,并使带有选择的回收器视图更容易一些。

    【讨论】:

      【解决方案2】:

      RecyclerView.adapter 有两个重要的函数需要重写:

      onCreateViewHolder(parent, viewType)
      onBindVIewHolder(viewholder, position)
      

      第一个函数用于扩充将在 recyclerview 中使用的视图,第二个函数用于将您拥有的数据绑定到此视图,从而在视图上设置正确的视图状态。

      recyclerview 本身只会膨胀一定数量的视图,然后会开始重新使用已经膨胀的视图(因此是 recyclerview)。因此,您需要为 onBindViewholder() 中的每个项目设置正确的状态,并在该位置使用集合中的项目来设置正确的 viewState。 对于您的示例:根据对象中的布尔值更改图标的颜色,例如:isPressed

      【讨论】:

      • 谢谢先生!并感谢您解释 onBindViewHolder 的目的,我在阅读您的帖子后设法解决了它。再次感谢
      【解决方案3】:

      你必须像这样保存实例

      if (isPressed) {
          icon.setCustomIcon();
      } else {
          icon.setDefaultIcon();    
      }
      

      如果你有一个自定义对象有一个布尔 isPressed 或类似的东西,这应该可以工作

      【讨论】:

        猜你喜欢
        • 2019-08-06
        • 1970-01-01
        • 2021-04-07
        • 2022-12-17
        • 2020-06-17
        • 2016-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多