美文网首页
为RecyclerView添加item的点击事件

为RecyclerView添加item的点击事件

作者: JohnKang | 来源:发表于2017-08-02 16:52 被阅读99次

    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 interface

    publicstaticinterfaceOnItemClickListener{

    voidonItemClick(Viewview,intposition);

    }

    声明一个这个接口的变量

    privateOnItemClickListenermOnItemClickListener=null;

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

    @Override

    publicViewHolderonCreateViewHolder(ViewGroupviewGroup,intviewType){

    Viewview=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);

    ViewHoldervh=newViewHolder(view);

    //将创建的View注册点击事件

    view.setOnClickListener(this);

    returnvh;

    }

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

    @Override

    publicvoidonClick(Viewv){

    if(mOnItemClickListener!=null){

    //注意这里使用getTag方法获取position

    mOnItemClickListener.onItemClick(v,(int)v.getTag());

    }

    }

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

    @Override

    publicvoidonBindViewHolder(ViewHolderviewHolder,intposition){

    viewHolder.mTextView.setText(datas[position]);

    //将position保存在itemView的Tag中,以便点击时进行获取

    viewHolder.itemView.setTag(position);

    }

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

    publicvoidsetOnItemClickListener(OnItemClickListenerlistener){

    this.mOnItemClickListener=listener;

    }

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

    在Activity中使用

    mRecyclerView=(RecyclerView)findViewById(R.id.my_recycler_view);

    //创建默认的线性LayoutManager

    mLayoutManager=newLinearLayoutManager(this);

    mRecyclerView.setLayoutManager(mLayoutManager);

    //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能

    mRecyclerView.setHasFixedSize(true);

    //创建并设置Adapter

    mAdapter=newMyAdapter(data);

    mRecyclerView.setAdapter(mAdapter);

    mAdapter.setOnItemClickListener(newOnItemClickListener(){

    @Override

    publicvoidonItemClick(Viewview,intposition){

    Toast.makeText(MainActivity.this,data[position],600).show();

    }

    });

    完整代码

    MyAdapter.java

    packagecom.example.recyclerviewdemo;

    importandroid.support.v7.widget.RecyclerView;

    importandroid.util.Log;

    importandroid.view.LayoutInflater;

    importandroid.view.View;

    importandroid.view.ViewGroup;

    importandroid.widget.TextView;

    publicclassMyAdapterextendsRecyclerView.AdapterimplementsView.OnClickListener{

    privateString[]datas;

    publicMyAdapter(String[]datas){

    this.datas=datas;

    }

    privateOnItemClickListenermOnItemClickListener=null;

    //define interface

    publicstaticinterfaceOnItemClickListener{

    voidonItemClick(Viewview,intposition);

    }

    @Override

    publicViewHolderonCreateViewHolder(ViewGroupviewGroup,intviewType){

    Viewview=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);

    ViewHoldervh=newViewHolder(view);

    //将创建的View注册点击事件

    view.setOnClickListener(this);

    returnvh;

    }

    @Override

    publicvoidonBindViewHolder(ViewHolderviewHolder,intposition){

    viewHolder.mTextView.setText(datas[position]);

    //将position保存在itemView的Tag中,以便点击时进行获取

    viewHolder.itemView.setTag(position);

    }

    @Override

    publicvoidonClick(Viewv){

    if(mOnItemClickListener!=null){

    //注意这里使用getTag方法获取position

    mOnItemClickListener.onItemClick(v,(int)v.getTag());

    }

    }

    publicvoidsetOnItemClickListener(OnItemClickListenerlistener){

    this.mOnItemClickListener=listener;

    }

    //获取数据的数量

    @Override

    publicintgetItemCount(){

    returndatas.length;

    }

    //自定义的ViewHolder,持有每个Item的的所有界面元素

    publicstaticclassViewHolderextendsRecyclerView.ViewHolder{

    publicTextViewmTextView;

    publicViewHolder(Viewview){

    super(view);

    mTextView=(TextView)view.findViewById(R.id.text);

    }

    }

    }

    item.xml

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="50dip"

    >

    android:id="@+id/text"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    />

    MainActivity.java

    packagecom.example.recyclerviewdemo;

    importcom.example.recyclerviewdemo.MyAdapter.OnItemClickListener;

    importandroid.support.v7.app.ActionBarActivity;

    importandroid.support.v7.widget.LinearLayoutManager;

    importandroid.support.v7.widget.RecyclerView;

    importandroid.os.Bundle;

    importandroid.view.Menu;

    importandroid.view.MenuItem;

    importandroid.view.View;

    importandroid.widget.Toast;

    publicclassMainActivityextendsActionBarActivity{

    privateRecyclerViewmRecyclerView;

    privateLinearLayoutManagermLayoutManager;

    privateMyAdaptermAdapter;

    privateString[]data=newString[]{"aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb"};

    @Override

    protectedvoidonCreate(BundlesavedInstanceState){

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    mRecyclerView=(RecyclerView)findViewById(R.id.my_recycler_view);

    //创建默认的线性LayoutManager

    mLayoutManager=newLinearLayoutManager(this);

    mRecyclerView.setLayoutManager(mLayoutManager);

    //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能

    mRecyclerView.setHasFixedSize(true);

    //创建并设置Adapter

    mAdapter=newMyAdapter(data);

    mRecyclerView.setAdapter(mAdapter);

    mAdapter.setOnItemClickListener(newOnItemClickListener(){

    @Override

    publicvoidonItemClick(Viewview,intposition){

    Toast.makeText(MainActivity.this,data[position],600).show();

    }

    });

    }

    @Override

    publicbooleanonCreateOptionsMenu(Menumenu){

    // Inflate the menu; this adds items to the action bar if it is present.

    getMenuInflater().inflate(R.menu.main,menu);

    returntrue;

    }

    @Override

    publicbooleanonOptionsItemSelected(MenuItemitem){

    // 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.

    intid=item.getItemId();

    if(id==R.id.action_settings){

    returntrue;

    }

    returnsuper.onOptionsItemSelected(item);

    }

    }

    activity_main.xml

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity">

    android:id="@+id/my_recycler_view"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:scrollbars="vertical"/>

    总结

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

    mListView.setOnItemClickListener(newOnItemClickListener(){

    publicvoidonItemClick(AdapterViewparent,Viewv,intposition,longid){

    ...

    }

    });

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

    相关文章

      网友评论

          本文标题:为RecyclerView添加item的点击事件

          本文链接:https://www.haomeiwen.com/subject/xulylxtx.html