有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
基于Jacob Tabak的回答(+1),我能够添加onLongClick监听器:
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 {
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
private OnItemClickListener mListener;
private 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 childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
}
}
});
}
@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 false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
然后你可以这样使用它:
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
// ...
}
@Override
public void onItemLongClick(View view, int position) {
// ...
}
}));
其他回答
我已经看了所有的答案,并不是很满意。我找到了更简单快捷的方法。想分享给未来的读者。
选择单个回收项目中的任何视图。 获取这个View的父视图(确保你施放了合适的ViewGroup) 将onClickListener设置为这个父节点。
示例代码(它是在适配器的onBindViewHolder方法中编写的):
@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
ConstraintLayout parent = (ConstraintLayout) holder.title.getParent();
parent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "Clicked recycler view item at position " + position, Toast.LENGTH_SHORT).show();
}
});
}
别白费力气了!这个特定用例的代码包含在Android Studio附带的Master/Detail Flow启动器项目中。
从Android Studio选择:
文件>新建>新建项目.... 在Phone and Tablet选项卡中选择如下所示的Master/Detail Flow。
用Kotlin或Java创建项目。 利润。
我不会在这里包括谷歌的ootb演示项目的代码,但我会概述谷歌提供的示例中的主要设计方法:
the item OnClickListener is created ONLY ONCE, and is assigned to a field in your RecyclerView.Adapter implementation. in the onBindViewHolder() you should set the same, pre-created onClickListener object on your ViewHolder instance with holder.itemView.setOnClickListener(mOnClickListener) (AVOID creating a new instance on every method call!); if you need to capture clicks on some specific elements inside the ViewHolder then extend ViewHolder and expose the elements you need as fields so that you can attach whatever listeners you need in onBindViewHolder() — and once again, do NOT re-create the listeners on every method call — initialise them as instance fields and attach them as needed. you can use .setTag() in order to pass state to your viewHolder, e.g. holder.itemView.setTag(mValues.get(position)); as used in the demo.
对我来说,最干净的方法就是这个。
适配器的构造函数
private class EnvironmentTypeRecyclerViewAdapter extends RecyclerView.Adapter<EnvironmentTypeRecyclerViewAdapter.ViewHolder>
{
private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener;
private List<Environment> mEnvironmentsData;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public ViewHolder(View v)
{
super(v);
v.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
Environment environment = mEnvironmentsData.get(getAdapterPosition());
if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null) {
mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment);
}
}
public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener)
{
mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener;
mEnvironmentsData = environments;
}
}
链接接口
private interface EnvironmentTypeRecyclerViewAdapterListener
{
void onListItemSelected(Environment environment);
}
我的方式
活动课上:
public class MyActivity extends AppCompatActivity implements EmployeeAdapter.ClickListener {
...
@Override
public void onClick(int position) { ... }
...
}
适配器类:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
...
@Override
public void onBindViewHolder(){
holder.textView1.setOnClickListener(v -> clickListener.onClick(position));
}
...
public interface ClickListener {
void onClick(int position);
}
...
}
你可以很容易地在ViewHolder类中定义setOnClickListener,如下所示:
public class ViewHolder extends RecyclerView.ViewHolder {
TextView product_name;
ViewHolder(View itemView) {
super(itemView);
product_name = (TextView) itemView.findViewById(R.id.product_name);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int itemPosition = getLayoutPosition();
Toast.makeText(getApplicationContext(), itemPosition + ":" + String.valueOf(product_name.getText()), Toast.LENGTH_SHORT).show();
}
});
}
}
推荐文章
- 警告: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++ ?