RecyclerView 的 OnClickListener

Vin*_*lya 4 android view onclicklistener android-recyclerview

与 ListView 不同,Android RecyclerView 的实现似乎太复杂了。由于 RecyclerView 子项没有 OnItemClickListener,因此我一直在尝试实现以下方法来注册单击事件:

final RecyclerView rv=(RecyclerView)findViewById(R.id.recycler_view);
    LinearLayoutManager llm=new LinearLayoutManager(this);
    rv.setLayoutManager(llm);
    MyRVAdapter rva=new MyRVAdapter(persons);
    rv.setAdapter(rva);

    rv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int itemPosition = rv.indexOfChild(v);
            Log.d("Tag", String.valueOf(itemPosition));
        }
    });
Run Code Online (Sandbox Code Playgroud)

由于某种原因,我无法让这段代码工作。点击事件根本没有注册!有人可以告诉我我做错了什么吗?我已经看到了一些解决方案,但我认为这应该可行。感谢您的帮助!

Sas*_*_KP 6

而不是为整个设置设置 onclicklistener ,而是在您的类RecyclerView的构造函数中设置ViewHolderAdapter.

一些示例代码类似于以下类,它是 recyclerview 适配器内的内部类。

     class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

      .....
        public ViewHolder(View itemView) {
            super(itemView);
           .......
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {

           .......
        }
    }
Run Code Online (Sandbox Code Playgroud)

onCreateViewHolder在适配器内部,将膨胀的视图传递给ViewGroup类似的构造函数,

 @Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.your_layout, viewGroup, false);
    ViewHolder viewHolder = new ViewHolder(v);
    return viewHolder;
}    
Run Code Online (Sandbox Code Playgroud)


Far*_*deh 5

虽然已经有一些答案,但我想我也可以提供它的实现以及解释。(完整的详细信息可以在我回答的另一个类似问题上找到)。

因此,要添加点击侦听器,您的内部ViewHolder类需要实现View.OnClickListener. 这是因为您将设置 an为 的构造函数的OnClickListener参数。让我告诉你我的意思:itemViewViewHolder

public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    TextView text1, text2;

    ExampleClickViewHolder(View itemView) {
        super(itemView);

        // we do this because we want to check when an item has been clicked:
        itemView.setOnClickListener(this);

        // now, like before, we assign our View variables
        title = (TextView) itemView.findViewById(R.id.text1);
        subtitle = (TextView) itemView.findViewById(R.id.text2);
    }

    @Override
    public void onClick(View v) {
        // The user may not set a click listener for list items, in which case our listener
        // will be null, so we need to check for this
        if (mOnEntryClickListener != null) {
            mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要添加的唯一其他内容是您的自定义接口Adapter和 setter 方法:

private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}
Run Code Online (Sandbox Code Playgroud)

这样您的新点击支持Adapter就完成了。

现在,让我们使用它...

    ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects);
    clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() {
        @Override
        public void onEntryClick(View view, int position) {
            // stuff that will happen when a list item is clicked
        }
    });
Run Code Online (Sandbox Code Playgroud)

这基本上就是您设置普通 的方式Adapter,只不过您使用您创建的 setter 方法来控制当您的用户单击特定列表项时您将执行的操作。

我在 GitHub 上的 Gist上制作了一组示例,其中显示了可以用作模板的完整 Java 文件,或者帮助您了解其Adapter工作原理。