有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
Recyclerview适配器与kotlin
在适配器中可以通过两种方式实现项目点击监听器。
第一种方法是使用界面
在你的活动课上:
class YourActivity : AppCompatActivity(), TestAdapter.ClickListener {
...
override fun itemClicked() {
}
...
}
在适配器类中:
class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder> {
...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView1.setOnClickListener {
clickListener.itemClicked(position)
}
}
...
interface ClickListener {
fun itemClicked(position : Int)
}
...
}
第二种方法是使用callBack调用
在适配器类中:
class MyAdapter(val callBack: (pos:Int) -> Unit) : RecyclerView.Adapter<MyAdapter.MyViewHolder> {
...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.textView1.setOnClickListener {
callBack(position)
}
}
}
在你的活动课上:
class YourActivity : AppCompatActivity() {
...
val testAdapter = TestAdapter(
callBack = { index ->
})
binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = testAdapter
...
}
其他回答
我们可以使用Java弱引用来实现这一点。 从语义上讲,视图持有者应该响应click事件或将其委托给正确的响应器。
我们的目标:
Viewholder应该对响应事件的类一无所知,除非它实现了某个接口。 点击处理程序应该得到被点击的视图在RecyclerView中的位置。 我们应该能够辨别视图持有人中单击了哪个视图。 保持所有组件之间的松散耦合,不要造成任何保留周期。
步骤:
Create an interface to handle click responses. Implement this interface in the Activity that will handle the click. Add a member variable in the RecyclerView Adapter to hold the Weak Reference and a constructor that sets it. Do the same in the RecyclerView ViewHolder and add a member variable to keep track of position. Set your on click listeners on any view you'd like in the ViewHolder, then callback to the responder to handle them. Change your onBindViewHolder method to set the position when binding. Pass the responder down to the ViewHolder. In the responder, you can now use getId() on the view to figure out which view was clicked.
这里是一个要点,这样你就可以看到它们是如何组合在一起的: RecyclerView点击处理
这里有一个更好的和不那么紧密耦合的方式来实现一个OnClickListener的RecyclerView。
用法片段:
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
// do whatever
}
@Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
RecyclerItemClickListener实现:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onLongItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
@Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){}
}
在kotlin中使用构造函数实现
初始化你的RecyclerView构造函数,如下所示:
class ListAdapter(
c: Context,
private var list: List<Project>,
private val itemClick: (Project) -> Unit
) : RecyclerView.Adapter<ListAdapter.ViewHolder>()
在onCreateViewHolder中使用itemClick返回:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):ProjectViewHolder {
val view = inflater.inflate(R.layout.list_item, parent, false)
return ViewHolder(view, itemClick)
}
你的onBindViewHolder:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bindProject(list[position])
}
然后用ViewHolder类创建bindProject函数。
class ViewHolder(
view: View,
private val itemClick: (Project) -> Unit
) : RecyclerView.ViewHolder(view) {
private val clientTextCount = 7
val titleTextView: TextView = view.projectTitleTextView
fun bindProject(project: Project) {
with(project) {
titleTextView.text = name
itemView.setOnClickListener { itemClick(this) }
}
}
}
最后在您的活动中用lazy初始化适配器
private val adapter: ListAdapter by lazy {
ListAdapter(this, projectList, {
// Here you can implement your onClick function.
})
}
在适配器中为RecyclerView添加新列表初始化以下方法:
fun setProjects(projects: List<Project>) {
projectList = projects
notifyDataSetChanged()
}
在你的活动中调用setProjects方法:
adapter.setProjects(projects)
就是这样。
对我来说,这是最好的方法:
class YourRecyclerAdapter extends RecyclerView.Adapter<ContactViewHolder> implements View.OnClickListener {
...
@Override
public void onClick(View view) {
int itemPosition = vRecycle.getChildPosition(view);
//And use itemPosition to get the item from your collection. This way you dont restrain the ViewHolder with a OnClick callback
}
...
}
太简单和有效了。
而不是实现接口视图。OnClickListener内的视图持有人或创建和接口和实现接口在您的活动- 我使用这段代码简单的OnClickListener实现。
public static class SimpleStringRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
// Your initializations goes here...
private List<String> mValues;
public static class ViewHolder extends RecyclerView.ViewHolder {
//create a variable mView
public final View mView;
/*All your row widgets goes here
public final ImageView mImageView;
public final TextView mTextView;*/
public ViewHolder(View view) {
super(view);
//Initialize it here
mView = view;
/* your row widgets initializations goes here
mImageView = (ImageView) view.findViewById(R.id.avatar);
mTextView = (TextView) view.findViewById(android.R.id.text1);*/
}
}
public String getValueAt(int position) {
return mValues.get(position);
}
public SimpleStringRecyclerViewAdapter(Context context, List<String> items) {
mBackground = mTypedValue.resourceId;
mValues = items;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
view.setBackgroundResource(mBackground);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mBoundString = mValues.get(position);
holder.mTextView.setText(mValues.get(position));
//Here it is simply write onItemClick listener here
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
Intent intent = new Intent(context, ExampleActivity.class);
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mValues.size();
}
}
推荐文章
- 警告: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++ ?