爲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的相關數據(這裏只是一個字符串)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章