为RecyclerView添加item的点击事件

来源:互联网 发布:网页设计是美工吗 编辑:程序博客网 时间:2024/05/22 10:34

RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一下观察者模式。

最终目的

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

原理

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

步骤

adapter中

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

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

//define interfacepublic static interface OnRecyclerViewItemClickListener {    void onItemClick(View view , String data);}

声明一个这个接口的变量

private OnRecyclerViewItemClickListener mOnItemClickListener = null;

@Overridepublic 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;}将点击事件转移给外面的调用者:@Overridepublic void onClick(View v) {    if (mOnItemClickListener != null) {        //注意这里使用getTag方法获取数据        mOnItemClickListener.onItemClick(v,(String)v.getTag());    }}注意上面调用接口的onItemClick()中的v.getTag()方法,这需要在onBindViewHolder()方法中设置和item相关的数据@Overridepublic void onBindViewHolder(ViewHolder viewHolder,  int position) {    viewHolder.mTextView.setText(datas[position]);    //将数据保存在itemView的Tag中,以便点击时进行获取    viewHolder.itemView.setTag(datas[position]);}最后暴露给外面的调用者,定义一个设置Listener的方法():public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {    this.mOnItemClickListener = listener;}以上所有步骤都发生在自定义的adapter中,典型的观察者模式,有点绕的地方在于,这里涉及到两个观察者模式的使用,view的setOnClickListener本来就是观察者模式,我们将这个观察者模式的事件监听传递给了我们自己的观察者模式。在Activity中使用mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);//创建默认的线性LayoutManagermLayoutManager = new LinearLayoutManager(this);mRecyclerView.setLayoutManager(mLayoutManager);//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能mRecyclerView.setHasFixedSize(true);//创建并设置AdaptermAdapter = 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.javapackage 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<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"><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"/>    </RelativeLayout>        MainActivity.javapackage 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

<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.RecyclerViewandroid:id="@+id/my_recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="vertical"/></RelativeLayout>

总结

在ListView中我们是调用ListView的setOnItemClickListener

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
原创粉丝点击