为RecyclerView添加item的点击事件(转载)

转载学习http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0327/2647.html

最终目的

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

原理

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

步骤

adapter中

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

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

1
2
3
4
     //define interface
     public static interface OnRecyclerViewItemClickListener {
         void onItemClick(View view , String data);
     }


声明一个这个接口的变量

1
     private OnRecyclerViewItemClickListener mOnItemClickListener =  null ;

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

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

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

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

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

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

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

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

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

在Activity中使用

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

完整代码

MyAdapter.java

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

item.xml

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

MainActivity.java

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

activity_main.xml

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

总结

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

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

而在我们这里是调用mAdapter的setOnItemClickListener。且回调方法public void onItemClick()的参数也不一致,ListView中有被点击item的position参数,而我们这里直接是被点击item的相关数据(这里只是一个字符串)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值