Android为RecyclerView添加item的点击事件

梦里梦外; 2022-06-01 06:51 457阅读 0赞

最终目的

模拟ListView的setOnItemClickListener()方法,调用者只须调用类似于setOnItemClickListener的东西就能获得被点击item的相关数据。

原理

为RecyclerView的每个子item设置setOnClickListener,然后在onClick中再调用一次对外封装的接口,将这个事件传递给外面的调用者。而“为RecyclerView的每个子item设置setOnClickListener”在Adapter中设置。其实直接在onClick中也能完全处理item的点击事件,但是这样会破坏代码的逻辑。

步骤

adapter中

自定义一个继承自RecyclerView.Adapter的MyAdapter。

1.在MyAdapter中定义如下接口,模拟ListView的OnItemClickListener:

  1. //define interface
  2. public static interface OnItemClickListener {
  3. void onItemClick(View view , int position);
  4. }

声明一个这个接口的变量

  1. private OnItemClickListener mOnItemClickListener = null;

在onCreateViewHolder()中为每个item添加点击事件

  1. @Override
  2. public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
  3. View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
  4. ViewHolder vh = new ViewHolder(view);
  5. //将创建的View注册点击事件
  6. view.setOnClickListener(this);
  7. return vh;
  8. }

将点击事件转移给外面的调用者:

  1. @Override
  2. public void onClick(View v) {
  3. if (mOnItemClickListener != null) {
  4. //注意这里使用getTag方法获取position
  5. mOnItemClickListener.onItemClick(v,(int)v.getTag());
  6. }
  7. }

注意上面调用接口的onItemClick()中的v.getTag()方法,这需要在onBindViewHolder()方法中设置和item的position

  1. @Override
  2. public void onBindViewHolder(ViewHolder viewHolder, int position) {
  3. viewHolder.mTextView.setText(datas[position]);
  4. //将position保存在itemView的Tag中,以便点击时进行获取
  5. viewHolder.itemView.setTag(position);
  6. }

最后暴露给外面的调用者,定义一个设置Listener的方法():

  1. public void setOnItemClickListener(OnItemClickListener listener) {
  2. this.mOnItemClickListener = listener;
  3. }

以上所有步骤都发生在自定义的adapter中,典型的观察者模式,有点绕的地方在于,这里涉及到两个观察者模式的使用,view的setOnClickListener本来就是观察者模式,我们将这个观察者模式的事件监听传递给了我们自己的观察者模式。

在Activity中使用

  1. mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
  2. //创建默认的线性LayoutManager
  3. mLayoutManager = new LinearLayoutManager(this);
  4. mRecyclerView.setLayoutManager(mLayoutManager);
  5. //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
  6. mRecyclerView.setHasFixedSize(true);
  7. //创建并设置Adapter
  8. mAdapter = new MyAdapter(data);
  9. mRecyclerView.setAdapter(mAdapter);
  10. mAdapter.setOnItemClickListener(new OnItemClickListener(){
  11. @Override
  12. public void onItemClick(View view , int position){
  13. Toast.makeText(MainActivity.this, data[position], 600).show();
  14. }
  15. });

完整代码

MyAdapter.java

  1. package com.example.recyclerviewdemo;
  2. import android.support.v7.widget.RecyclerView;
  3. import android.util.Log;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. import android.widget.TextView;
  8. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener{
  9. private String[] datas;
  10. public MyAdapter(String[] datas) {
  11. this.datas = datas;
  12. }
  13. private OnItemClickListener mOnItemClickListener = null;
  14. //define interface
  15. public static interface OnItemClickListener {
  16. void onItemClick(View view , int position);
  17. }
  18. @Override
  19. public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
  20. View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
  21. ViewHolder vh = new ViewHolder(view);
  22. //将创建的View注册点击事件
  23. view.setOnClickListener(this);
  24. return vh;
  25. }
  26. @Override
  27. public void onBindViewHolder(ViewHolder viewHolder, int position) {
  28. viewHolder.mTextView.setText(datas[position]);
  29. //将position保存在itemView的Tag中,以便点击时进行获取
  30. viewHolder.itemView.setTag(position);
  31. }
  32. @Override
  33. public void onClick(View v) {
  34. if (mOnItemClickListener != null) {
  35. //注意这里使用getTag方法获取position
  36. mOnItemClickListener.onItemClick(v,(int)v.getTag());
  37. }
  38. }
  39. public void setOnItemClickListener(OnItemClickListener listener) {
  40. this.mOnItemClickListener = listener;
  41. }
  42. //获取数据的数量
  43. @Override
  44. public int getItemCount() {
  45. return datas.length;
  46. }
  47. //自定义的ViewHolder,持有每个Item的的所有界面元素
  48. public static class ViewHolder extends RecyclerView.ViewHolder {
  49. public TextView mTextView;
  50. public ViewHolder(View view){
  51. super(view);
  52. mTextView = (TextView) view.findViewById(R.id.text);
  53. }
  54. }
  55. }

item.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="50dip"
  5. >
  6. <TextView
  7. android:id="@+id/text"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. />
  11. </RelativeLayout>

MainActivity.java

  1. package com.example.recyclerviewdemo;
  2. import com.example.recyclerviewdemo.MyAdapter.OnItemClickListener;
  3. import android.support.v7.app.ActionBarActivity;
  4. import android.support.v7.widget.LinearLayoutManager;
  5. import android.support.v7.widget.RecyclerView;
  6. import android.os.Bundle;
  7. import android.view.Menu;
  8. import android.view.MenuItem;
  9. import android.view.View;
  10. import android.widget.Toast;
  11. public class MainActivity extends ActionBarActivity {
  12. private RecyclerView mRecyclerView;
  13. private LinearLayoutManager mLayoutManager;
  14. private MyAdapter mAdapter;
  15. private String[] data= new String[] { "aa","bb", "aa","bb", "aa","bb", "aa","bb", "aa","bb","aa","bb", "aa","bb", "aa","bb", "aa","bb", "aa","bb" };
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_main);
  20. mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
  21. //创建默认的线性LayoutManager
  22. mLayoutManager = new LinearLayoutManager(this);
  23. mRecyclerView.setLayoutManager(mLayoutManager);
  24. //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
  25. mRecyclerView.setHasFixedSize(true);
  26. //创建并设置Adapter
  27. mAdapter = new MyAdapter(data);
  28. mRecyclerView.setAdapter(mAdapter);
  29. mAdapter.setOnItemClickListener(new OnItemClickListener(){
  30. @Override
  31. public void onItemClick(View view , int position){
  32. Toast.makeText(MainActivity.this, data[position], 600).show();
  33. }
  34. });
  35. }
  36. @Override
  37. public boolean onCreateOptionsMenu(Menu menu) {
  38. // Inflate the menu; this adds items to the action bar if it is present.
  39. getMenuInflater().inflate(R.menu.main, menu);
  40. return true;
  41. }
  42. @Override
  43. public boolean onOptionsItemSelected(MenuItem item) {
  44. // Handle action bar item clicks here. The action bar will
  45. // automatically handle clicks on the Home/Up button, so long
  46. // as you specify a parent activity in AndroidManifest.xml.
  47. int id = item.getItemId();
  48. if (id == R.id.action_settings) {
  49. return true;
  50. }
  51. return super.onOptionsItemSelected(item);
  52. }
  53. }

activity_main.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity">
  6. <android.support.v7.widget.RecyclerView
  7. android:id="@+id/my_recycler_view"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:scrollbars="vertical"/>
  11. </RelativeLayout>

总结

在ListView中我们是调用ListView的setOnItemClickListener:

  1. mListView.setOnItemClickListener(new OnItemClickListener() {
  2. public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
  3. ...
  4. }
  5. });

而在我们这里是调用mAdapter的setOnItemClickListener。

发表评论

表情:
评论列表 (有 0 条评论,457人围观)

还没有评论,来说两句吧...

相关阅读