有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。


当前回答

nhaarman答案的Kotlin实现:

mRecyclerView.addOnItemTouchListener(object  : RecyclerItemClickListener(this, mRecyclerView,object :RecyclerItemClickListener.OnItemClickListener{
            override fun onItemClick(view: View, position: Int) {

            }

            override fun onLongItemClick(view: View?, position: Int) {

            }
}){})

RecyclerItemClickListener.java:

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View


open class RecyclerItemClickListener(context: Context, recyclerView: RecyclerView, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {

    private var mGestureDetector: GestureDetector

    interface OnItemClickListener {
        fun onItemClick(view: View, position: Int)

        fun onLongItemClick(view: View?, position: Int)
    }

    init {
        mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
            override fun onSingleTapUp(e: MotionEvent): Boolean {
                return true
            }

            override fun onLongPress(e: MotionEvent) {
                val child = recyclerView.findChildViewUnder(e.x, e.y)
                if (child != null && mListener != null) {
                    mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child))
                }
            }
        })
    }

    override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
        val childView = view.findChildViewUnder(e.x, e.y)
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildAdapterPosition(childView))
            return true
        }
        return false
    }

    override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}

其他回答

以下是我所做的。这个解决方案同时支持onClick和onLongClick在两个RecyclerView项目和视图内的RecyclerView项目(内部视图)。

我在我选择的视图上标记viewHolder:

public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item, null);
    ViewHolder viewHolder = new ViewHolder(itemView);

    itemView.setOnClickListener( this);
    itemView.setOnLongClickListener(this);
    viewHolder.imageIV.setOnClickListener(this);
    viewHolder.imageIV.setOnLongClickListener(this);

    viewHolder.imageIV.setTag(viewHolder);
    itemView.setTag(viewHolder);

    return viewHolder;
}

我使用holder.getPosition()在onClick()方法中检索位置(onLongClick类似):

public void onClick(View view) {
    ViewHolder holder = (ViewHolder) view.getTag();
    int position = holder.getPosition();

    if (view.getId() == holder.imageIV.getId()){
        Toast.makeText(context, "imageIV onClick at" + position, Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(context, "RecyclerView Item onClick at " + position, Toast.LENGTH_SHORT).show();
    }
}

带有getChildPosition的变体也可以工作。请注意,对于内部视图,在onClick()中使用:

int position = recyclerView.getChildPosition((View)view.getParent());

在我看来,这个解决方案的优点是,当一个人点击图像,只有onclick()图像侦听器被调用,而当我结合Jacob的解决方案为一个RecyclerView项目视图和我的解决方案为内部视图的RecyclerView项目视图onclick()也被调用(当点击图像)。

您可以将clickListener传递给适配器。

在活动中:

private View.OnClickListener mItemClick = new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        Intent intent = null;
        int position = list.getChildPosition(v);
        switch (position) {
            case 0:
                intent = new Intent(MainActivity.this, LeakCanaryActivity.class);
                break;
            case 1:
                intent = new Intent(MainActivity.this, ButterKnifeFragmentActivity.class);
                break;
        }
        if (intent != null) {
            MainActivity.this.startActivity(intent);
        }
    }
};

然后将它传递给适配器:

MainAdapter mainAdapter = new MainAdapter(this, mItemClick);

在适配器的onCreateViewHolder中:

 @Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
    View itemView = activity.getLayoutInflater().inflate(R.layout.main_adapter_item, viewGroup, false);
    ViewHolder holder = new ViewHolder(itemView);
    itemView.setOnClickListener(mItemClick);
    return holder;
}

这就是重用View的方法。OnClickListener:

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyviewHolder>
    implements View.OnClickListener

在ViewHoder中获取项目布局的父视图:

public class MyviewHolder extends RecyclerView.ViewHolder {

    LinearLayout linearLayout;

    public MyviewHolder(View itemView) {
        super(itemView);
        linearLayout = itemView.findViewById(R.id.linear_layout_item);
    }
}

在onBindViewHolder中设置标签为位置:

@Override
public void onBindViewHolder(MyviewHolder holder, int position) {
    holder.linearLayout.setTag(position);
    holder.linearLayout.setOnClickListener(this);
}

在你的onClick实现中:

@Override
public void onClick(View v) {
    int position = (int) v.getTag();

    switch (v.getId()) {
        case R.id.linear_layout_item:
            // do some thing with position 
            break;
    }
}

这就是我最后需要的东西,以防有人发现它有用:

public static class ViewHolder extends RecyclerView.ViewHolder {

    public ViewHolder(View item) {

        super(item);
        item.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("RecyclerView", "onClick:" + getAdapterPosition());
            }
        });

    }
}

来源:http://blog.csdn.net/jwzhangjie/article/details/36868515

查看类似的问题@CommonsWare的评论链接到this,它在viewHolder中实现了OnClickListener接口。

下面是ViewHolder的一个简单例子:

/** Declare global with in adapter class. */
TextView textView;

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

    private ViewHolder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        textView = (TextView) view.findViewById(android.R.id.text1);   
    }

    @Override
    public void onClick(View view) {
        Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
         
        /** Go through each item if you have few items within RecyclerView. */
        if (getLayoutPosition() == 0) {
           // Do whatever you want here
        } else if(getLayoutPosition() == 1) { 
           // Do whatever you want here
        } else if(getLayoutPosition() == 2) {
           // Do whatever you want here
        }

        /** Or you can use For loop if you have long list of items. */
        for (int i = 0; i < exampleList.size(); i++) {
            // Do whatever you want here
        }
    }
}

在你的RecyclerView中创建ViewHolder。适配器看起来像这样:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext())
    View view = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
    return new ViewHolder(view);
}