如何向RecyclerView添加点击事件监听器

10

我正在开发一个简单的记事本应用程序,首先我使用了ListView来显示所有的笔记。但现在我正在使用RecyclerView。当我使用ListView时,我使用OnItemClickListener将数据传递到另一个活动中以编辑该笔记。现在我对RecyclerView应该怎么做感到困惑。

对于ListView,我正在使用以下内容:

 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            name = filenames.get(position).getName();
            note = filenames.get(position).getShorttext();
            Alert(); // this method is in main activity 

        }
    });*/  


  public void Alert()
   {
    final AlertDialog dialog;
    View mview = getLayoutInflater().inflate(R.layout.dialog_pass,null);
    final EditText mEdittext = (EditText) mview.findViewById(R.id.Epass);
    AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
    mBuilder.setView(mview);
    mBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            String col = mEdittext.getText().toString();
            String password = dBhelper.searchpass(col);
            if (col.equals(password)) {
                Intent intent =  new Intent(MainActivity.this,Note2.class);
                intent.putExtra("Name",name);
                intent.putExtra("Note",note);
                startActivity(intent);
            } else {
                Toast temp = Toast.makeText(MainActivity.this, "Password does not match", Toast.LENGTH_SHORT);
                temp.show();
            }

        }
    });
    mBuilder.setNegativeButton("Cancel",null);
    mBuilder.setCancelable(false);
    dialog = mBuilder.create();
    dialog.show();

     }

现在我该怎么做来实现 Recycle View,请帮忙。

  public class RecycleViewAdapter extends 
  RecyclerView.Adapter<RecycleViewHolder> {// Recyclerview will extend to
  private List<FileName> fileNames;
  private Context context;

  public RecycleViewAdapter(Context context,List<FileName> fileNames) {
    this.context = context;
    this.fileNames = fileNames;
@Override
public RecycleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater mInflater = LayoutInflater.from(parent.getContext());

    ViewGroup mainGroup = (ViewGroup) mInflater.inflate(
            R.layout.grid_item, parent, false);
    RecycleViewHolder listHolder = new RecycleViewHolder(mainGroup);
    return listHolder;

}

@Override
public void onBindViewHolder(RecycleViewHolder holder, final int position) {
    final FileName model = fileNames.get(position);
    RecycleViewHolder mainHolder = (RecycleViewHolder) holder;// holder
    mainHolder.title.setText(model.getName());
    mainHolder.note.setText(model.getShorttext());

}

@Override
public int getItemCount() {
    return (null != fileNames ? fileNames.size() : 0);
  }

https://dev59.com/m2Af5IYBdhLWcg3wOQi2 - PEHLAJ
https://dev59.com/ylsX5IYBdhLWcg3wNdHj#40134429 - H4SN
8个回答

32

你可以通过两种方式来处理这个问题

1). 手势触摸 https://www.google.co.in/amp/sapandiwakar.in/recycler-view-item-click-handler/amp/

2). 在适配器中使用接口 https://antonioleiva.com/recyclerview-listener/

我建议使用第二种方式,即使用接口

如何为recycleritemclick使用接口

public class RecycleViewAdapter extends 
  RecyclerView.Adapter<RecycleViewHolder> {// Recyclerview will extend to
  private List<FileName> fileNames;
  private Context context;

//declare interface 
  private OnItemClicked onClick;

//make interface like this
  public interface OnItemClicked {
        void onItemClick(int position);
  }

  public RecycleViewAdapter(Context context,List<FileName> fileNames) {
    this.context = context;
    this.fileNames = fileNames;
  }

现在将点击分配给界面

@Override
public void onBindViewHolder(RecycleViewHolder holder, final int position) {
  //............//
  holder.title.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
        onClick.onItemClick(position);
     }
  });
}

在适配器类的末尾大括号上方创建一个方法,将itemclick分配给接口

public void setOnClick(OnItemClicked onClick){
    this.onClick=onClick;
}

在MainActivity.java中,将项目点击与适配器绑定

public class MainActivity extends Activity implements OnItemClicked {
 
    private RecyclerView mRecyclerView;
    private CityAdapter mAdapter;
    private List<City> cities;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_city);

        mRecyclerView = (RecyclerView)findViewById(R.id.list);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        
        mAdapter = new CityAdapter(cities, R.layout.row_city, this);
        mRecyclerView.setAdapter(mAdapter);
 
        mAdapter.setOnClick(MainActivity.this); // Bind the listener
    }
 
    @Override
    public void onItemClick(int position) {
    // The onClick implementation of the RecyclerView item click
    //ur intent code here
    }
}

请参考如何在Kotlin中处理RecyclerView的项点击事件?

还有疑问?请评论。


我想通过Intent传递数据,但在OnClick上它不起作用 :( - faiz mir
你创建了接口吗? - Lokesh Desai
请不要告诉我应该在界面上写什么代码,我是安卓新手。 - faiz mir
公共类 MainActivity 扩展自 Activity,实现 RecycleViewAdapter.OnItemClicked 接口 //请确保您在 MainActivity 上实现了适配器接口 - Lokesh Desai
非常感谢您,您救了我的命 :) 上帝保佑您。 - faiz mir
如果这是在一个方法或点击事件中,请改用“mAdapter.setOnClick(ِactivity.this)”来替换上述内容。 - AhuraMazda

11

最简单的解决方法是访问holder类的"itemView"公共变量,并在其上设置onClick监听器。

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, NewActivity.class);
                intent.putExtra("FileName", list.get(position));
                context.startActivity(intent);
            }
        });        
}

1

首先将此类添加到您的软件包中

public class MyTouchListener implements RecyclerView.OnItemTouchListener {


/*Change these as per your need*/
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private static final int SWIPE_MAX_OFF_PATH = 250;

private OnTouchActionListener mOnTouchActionListener;
private GestureDetectorCompat mGestureDetector;

public static interface OnTouchActionListener {
    public void onLeftSwipe(View view, int position);
    public void onRightSwipe(View view, int position);
    public void onClick(View view, int position);
}

public MyTouchListener(Context context, final RecyclerView recyclerView,
                             OnTouchActionListener onTouchActionListener){

    mOnTouchActionListener = onTouchActionListener;
    mGestureDetector = new GestureDetectorCompat(context,new GestureDetector.SimpleOnGestureListener(){

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            // Find the item view that was swiped based on the coordinates
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            int childPosition = recyclerView.getChildPosition(child);
            mOnTouchActionListener.onClick(child, childPosition);
            return false;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2,
                               float velocityX, float velocityY) {

            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
                    return false;
                }

                // Find the item view that was swiped based on the coordinates
                View child = recyclerView.findChildViewUnder(e1.getX(), e1.getY());
                int childPosition = recyclerView.getChildPosition(child);

                // right to left swipe
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                    if (mOnTouchActionListener != null && child != null) {
                        mOnTouchActionListener.onLeftSwipe(child, childPosition);
                    }

                } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    if (mOnTouchActionListener != null && child != null) {
                        mOnTouchActionListener.onRightSwipe(child, childPosition);
                    }
                }
            } catch (Exception e) {
                // nothing
            }

            return false;
        }
    });
}

@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
    mGestureDetector.onTouchEvent(e);
    return false;
}

@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    // do nothing
}}

然后像这样添加addOnItemTouchListener:
myRecyclerView.addOnItemTouchListener(new MyTouchListener(mContext,
            myRecyclerView,
            new MyTouchListener.OnTouchActionListener() {
                @Override
                public void onLeftSwipe(View view, int position) {//code as per your need
                }

                @Override
                public void onRightSwipe(View view, int position) {//code as per your need
                }

                @Override
                public void onClick(View view, int position) {//code as per your need
                }
            }));

1
将您的适配器更改为此。
    public class RecycleViewAdapter extends
        RecyclerView.Adapter<RecycleViewHolder> {// Recyclerview will extend to
    private List<FileName> fileNames;
    private Context context;
    private OnItemClicked listener;

    public RecycleViewAdapter(Context context, List<FileName> fileNames, OnItemClicked  listener) {
        this.context = context;
        this.fileNames = fileNames;
        this.listener = listener;
    }

    public BookingHistoryFragment() {
        // Required empty public constructor
    }

    @Override
    public RecycleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater mInflater = LayoutInflater.from(parent.getContext());

        ViewGroup mainGroup = (ViewGroup) mInflater.inflate(
                R.layout.grid_item, parent, false);
        RecycleViewHolder listHolder = new RecycleViewHolder(mainGroup);

        return listHolder;

    }

    @Override
    public void onBindViewHolder(RecycleViewHolder holder, final int position) {
        final FileName model = fileNames.get(position);
        RecycleViewHolder mainHolder = (RecycleViewHolder) holder;// holder
        mainHolder.title.setText(model.getName());
        mainHolder.note.setText(model.getShorttext());

        // Add click listener for root view
        view.getRootView().setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            listener.onItemClick(view, position)
        }
        });
    }

    @Override
    public int getItemCount() {
        return (null != fileNames ? fileNames.size() : 0);
    }

    public interface OnItemClicked {
        void onItemClick(View view, int position);
    }
}

现在在从活动或片段初始化时,将ItemClickInterface传递给适配器构造函数。 而不是:
RecycleViewAdapter adapter = new RecycleViewAdapter(this, filenames);

使用这个:
RecycleViewAdapter adapter = new RecycleViewAdapter(this, filenames, new RecycleViewAdapter.OnItemClicked () {
@Override
      public void onItemClick(View view, Position position) {

      }
});

0

所以,不确定是否有人感兴趣或者我的方法存在问题,但是我为自己的个人使用想出了一个更简单的方法。

该项的XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeightLarge"
    android:background="@drawable/recycborder">


    <TextView
        android:id="@+id/recycText"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center"
        android:onClick="recycClick"
        android:textColor="@color/black"
        android:textSize="16sp" />

</RelativeLayout>

在onBindViewHolder方法中,将标签设置为所需的任何信息。名称、位置、显示的文本、显示的图片等等。
@Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        holder.recycText.setText(lstAllInfo.get(position));
        holder.recycText.setTag(lstAllInfo.get(position));

    }

在你想处理项目点击的方法中:

 public void recycClick(View v) {
        String test = v.getTag().toString();
        Toast.makeText(getApplicationContext(), ("You clicked: "  + test), Toast.LENGTH_LONG).show();
    }

我认为这种方法存在一些限制。标签可能无法容纳您需要的数据,或者可能由于回收视图无法访问正确的活动而导致单击事件无法响应。个人而言,我正在使用它来开发Android Wear应用程序,并且效果非常好,所以我想发布这篇文章,以防万一,因为这比其他方法要简单得多。


0

Recyclerview with click listener

在您的适配器类中创建一个接口。
public interface SelectedUser{

    void selectedUser(UserModel userModel);

}

在你的适配器视图持有者类中监听点击事件。
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selectedUser.selectedUser(userModelList.get(getAdapterPosition()));
            }
        });

最后在你的活动中实现你的接口并重写该方法。

   @Override
    public void selectedUser(UserModel userModel) {

        startActivity(new Intent(MainActivity.this, SelectedUserActivity.class).putExtra("data",userModel));



    }

完整教程和源代码请使用下面的链接。 带有点击监听器的Recyclerview


0

将以下代码放入您的持有类中尝试一下... 它能够正常工作且易于使用:

public class RecyclerViewHolder extends RecyclerView.ViewHolder {

        public ItemHolder(@NonNull final View recyclerView) {
            super(recyclerView)

            recyclerView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();

                }
            });
        }
    }

0
将以下代码添加到您的RecyclerView适配器中。
    private OnItemClicked mListener;

    public RecycleViewAdapter(Context context, OnItemClicked listener, List<FileName> fileNames) {
        //............//
        this.mListener = listener;
    }

    @Override
    public void onBindViewHolder(RecycleViewHolder holder, final int position) {
        //............//
        mainHolder.title.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.onItemClick(position);
            }
        });

    }

    public interface OnItemClicked {
        void onItemClick(int position);
    }

将您的Activity/Fragment实现到RecyclerViewAdapter.OnItemClicked中

要通过Intent传递,您可以在Activity/Fragment中编写以下代码

    @Override
    public void onItemClick(int position) {
        Intent intent = new Intent(mContext, YourActivity.class);
        intent.putExtra(YourActivity.ARG_FILE, filnames.get(position));
        startActivity(intent);
    }

但我想将数据传递到另一个活动中,我该怎么做? - faiz mir
当我尝试在适配器上放置Intent时,它会给我一个错误。 - faiz mir
修改后的答案,你能说明一下那个Intent错误吗?也许你在通过Intent传递值时实现有误。 - Krunal Kapadiya
在OnItemClicked上显示错误 //无法解析符号 - faiz mir
请检查如何使用接口。 - Krunal Kapadiya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接