有人使用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);
}
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 碎片中的onCreateOptionsMenu
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?