在RecyclerView中选择项目

时间:2015-02-17 20:45:10

标签: android android-recyclerview

有人提出过类似的问题,但我不能让他们中的任何一个工作。

我想要的是在RecyclerView中选择项目,更改该项目视图的背景,并存储所选项目的位置。

主要问题是你有onCreateViewHolder(在适配器中),onBindViewHolder(在适配器中)和ViewHolder构造函数,并且每个人都在使用不同的方法。 现在,我甚至不知道将onClickListener放在哪里(在以前的项目中我把它放在ViewHolder中),因为人们也建议使用其他两种方法。

我的想法是将每个ViewHolder(或View)存储在列表中,这样我就可以引用每一行,并从那里更改背景。但这对我不起作用,因为当我尝试从三个地方(onCreateVH,onBindVH,VH类)中的任何一个添加到View(或ViewHolders)列表时,我的应用程序因某种原因崩溃(空指针ex)。

有什么建议吗?在哪里以及如何实施它?

2 个答案:

答案 0 :(得分:12)

使全局变量存储位置并处理ViewHolder中的点击侦听器。 Onclick项,更改全局位置值,如

textView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        globalPosition=getAdapterPosition();
        notifyDataSetChanged();
    }
});

然后在onBindViewHolder

if(postion==globalPosition)
{
    //change color like
    textview.setTextColor(Color.RED);
}
else
{
    //revert back to regular color 
    textview.setTextColor(Color.WHITE);
}

使用此代码,您单击的项目将变为红色,而其他所有项目将为白色。

答案 1 :(得分:1)

首先,您询问了将onClickListener放在何处 - 您应该将它放在onBindViewHolder中。您还可以在项目的ViewHolder类中附加onClickListener,如下所示:

public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                }
            });
        }
    }

至于实现单个选择行为,这里给出的答案有效,但是如果你有很多项目,那么调用onNotifyDatasetChanged对于性能是不利的,因为它每次都从头开始重新绑定所有视图。

Rafiduzzaman Sonnet提供的链接是一个很好的教程,可以理解很多关于设置RecyclerView的内容,但我认为它会使单一选择行为变得复杂。我将全面回答提供使其工作所需的一切。以下是我实现单一选择行为的方法:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    final YourItemViewHolder itemViewHolder = (YourItemViewHolder) holder;
    //This will remember which one was selected
    itemViewHolder.getItemSelectionIndicator()
            .setSelected(position == mSelectedPosition);
        itemViewHolder.getItemWrapperView()
            .setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(mLogTag, "Tapped on " + position);
                    //This is the previous selection
                    notifyItemChanged(mSelectedPosition);
                    itemViewHolder.getItemSelectionIndicator().setSelected(true);
                    mSelectedPosition = position;
                    //This is the new selection
                    notifyItemChanged(position);
                }
            });

getItemSelectionIndicator()getItemWrapperView()是项目ViewHolder中的方法,它返回项目布局中的特定视图。 ItemWrapperView可能是包装整个项目的最顶级的Linear / RelativeLayout。如果用户点击项目视图中的任何位置,则在其上设置点击监听器将确保点击工作。

ItemSelectionIndicator可以是已设置状态列表可绘制背景的Linear或RelativeLayout。这意味着当它被设置为选中时,它会自动显示一个可绘制的形状以指示选择。如果将其设置为未选中,则会自动删除drawable。这是指标视图的样子:

<RelativeLayout
        android:id="@+id/selection_indicator"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/selection_indicator_state_list"/>

这是res / drawable中的selection_indicator_state_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Selected background -->
    <item android:state_selected="true"
          android:drawable="@drawable/item_selection_shape"/>
    <!-- Unselected background -->
    <item android:state_selected="false"
        android:drawable="@color/transparent"/>
</selector>

这是res / drawable中的item_selection_shape.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    //22 is value of transparency, BDBDBD is the color
    <solid android:color="#22BDBDBD"/>
    <stroke android:width="2dp" android:color="@color/md_blue_600"/>
    <corners
        android:radius="3dp"/>
</shape>