RecyclerView使用攻略

简介

RecyclerView是什么?
  • RecycleView是一个用于在有限的窗口中展示大量数据集的控件
  • Google用于代替ListView的滑动组件
RecyclerView的优缺点
优点

由名字可知,RecyclerView,回收复用视图,RecyclerView只管回收与复用View,其他的你可以自己去设置,一个类实现一个功能,高度的解耦

缺点

RecyclerView实现控制点击、长按事件较为麻烦,需要自己写

详解

一、知识储备

RecylerView高度解耦,一个类实现一块功能,使用前需要先了解一下类

  • LayoutManager

布局管理器,默认提供LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager三大类,分别可以实现ListView,GridView以及流式布局的列表效果。

  • Adapter

适配器,适配数据如何显示,通过实现RecyclerView.Adapter接口中的方法实现数据的适配。
同时,RecyclerView的适配器强制要求了我们必须要用Viewholder,让性能得到优化,而且getView方法不需自己写,我们只需要写好Viewholder,View的复用已经封装好了。

  • ItemDecoration

Decoration 的英文意思是装饰物的意思,引申到这里来,肯定也是与 RecyclerView 的界面装饰有关。我们常见的就是分割线和item间距的配置

  • SnapHelper

如果每个Item显示⼀屏、按⻚来显示,可以通过设置此类快速实现,有SnapHelper 、LinearSnapHelper 、PagerSnapHelper这三个类

  • itemAnimator

这个类可以实现item的增删动画,不想设置的话它的默认效果也挺好的。

二、使用步骤

RecyclerView的使用步骤大致是这样固定的,效果和性能在于细节

使用步骤:
1、创建RecyclerView 通常在xml中配置
2、代码中设置属性
  确定布局样式 设置layoutManager
  确定数据源
3、定义一个Adapter实现RecyclerView.Adapter接口中的方法
 RecyclerView通过接口中的方法访问数据
  a、创建一个类继承于 RecyclerView.ViewHolder,重复利用
   b、重写adapter的接口方法
   getItemCount:确定RecyclerView中有多少个item
    onCreateViewHolder:确定每个item的具体视图
   onBindViewHolder:绑定视图
4、设置item装饰器 addItemDecoration
  1)系统提供的 DividerItemDecoration 分割线
  2)⾃⼰创建⼀个类继承于ItemDecoration 重写onDraw或者onDrawOver、getItemOffset

  1. 如果每个Item显示⼀屏 按⻚来显示 SnapHelper 、LinearSnapHelper 、 PagerSnapHelper

三、使用案例

1、创建一个工程,在xml中加入RecyclerView控件(最新版RecyclerView在androidx包,老版本为v7包),本案例直接在activity_main.xml中加



    


2、在MainActivity中获取RecyclerView控件,设置相关属性

由于AndroidStudio升级到4.1后,kotlin不默认使用id获取控件,而是建议用ViewBinding绑定控件,在此使用ViewBinding(即运行时为activity_main.xml生成一个ActivityMainBinding的类)

class MainActivity : AppCompatActivity() {
    /** AS4.1版本不默认支持用id访问控件     这里使用ViewBinding
     * 如果想要继续使用id访问控件  模块的build.gradle中加入  id 'kotlin-android-extensions'
     * 这里默认生成了ActivityMainBinding的类,此类关联了activity_main.xml
     */
    private var mBinding: ActivityMainBinding? = null
    private val dataSource:ArrayList = ArrayList()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //绑定xml
        mBinding = ActivityMainBinding.inflate(LayoutInflater.from(this))
        //设置为xml的根容器    即ConstraintLayout
        setContentView(mBinding?.root)

        //设置布局样式
//        mBinding?.mRecyclerView?.layoutManager = LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false)
        mBinding?.mRecyclerView?.layoutManager = StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL)
                //确定数据源
        for (i in 1..10){
            if (i % 2 == 0){
                dataSource.add(R.drawable.sy)
            }else{
                dataSource.add(R.drawable.gl)
            }
        }

        //设置适配器
        mBinding?.mRecyclerView?.adapter = MainAdapter(dataSource)

        //辅助类   使得滑动如翻页
        PagerSnapHelper().attachToRecyclerView(mBinding?.mRecyclerView)

        //设置装饰decoration 间隔、分割线等
        mBinding?.mRecyclerView?.addItemDecoration(MyItemDecoration())
    }
}
3、创建item显示样式的xml

即用xml编写RecyclerView的每一个item显示需要的控件和布局,在adapter中进行解析和数据绑定




    

    


4、创建一个类继承于RecyclerView.Adapter

通过实现其接口方法对RecyclerView进行适配,解释请看代码注释

class MainAdapter: RecyclerView.Adapter {

    lateinit var imageDataSource:ArrayList

    constructor(images:ArrayList){
        this.imageDataSource = images
    }

    //确定每个item的具体视图
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHold {
        //获取xml的视图  xml-》View
        //如果知道一个View  就可以通过这个view获取其上下文content
        val layoutInflater = LayoutInflater.from(parent.context)
        val itemView = layoutInflater.inflate(R.layout.main_recycler_item,parent,false)
//        val itemView = layoutInflater.inflate(R.layout.card_item,parent,false)
        return  MyViewHold(itemView)
    }


    //视图解析出来之后 需不需要将数据绑定到上面
    @SuppressLint("WrongConstant")
    override fun onBindViewHolder(holder: MyViewHold, position: Int) {
        holder.iconImageView.setImageResource(imageDataSource[position])
        holder.titleView.text = if (position%2 ==0) "银河以北,吾彦最美" else "银河以南,为彦而燃"
     //item点击事件
        holder.iconImageView.setOnClickListener{
            Toast.makeText(holder.iconImageView.context,holder.titleView.text,1000).show()
        }
    }

    //确定RecyclerView中有多少个 Item
    override fun getItemCount(): Int {
        return imageDataSource.size
    }

    //传递来的view 是RecyclerView显示的每一个item
    class MyViewHold: RecyclerView.ViewHolder{
        lateinit var titleView:TextView
        lateinit var iconImageView: ImageView
        constructor(itemView:View):super(itemView){
            titleView = itemView.findViewById(R.id.titleTextView)
            iconImageView = itemView.findViewById(R.id.iconImageView)
        }
    }

}
5、设置itemDecoration

创建一个类继承于RecyclerView.ItemDecoration,设置间隔的话实现其getItemOffsets方法,再到MainActivity中设置recyclerView的itemDecoration

class MyItemDecoration: RecyclerView.ItemDecoration() {
    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        outRect.set(10,10,10,10)
    }
}
6、设置SnapHelper,翻页效果等
//辅助类   使得滑动如翻页
 PagerSnapHelper().attachToRecyclerView(mBinding?.mRecyclerView)
7、设置点击事件

在onCreateViewHolder中设置

//确定每个item的具体视图
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHold {
        //获取xml的视图  xml-》View
        //如果知道一个View  就可以通过这个view获取其上下文content
        val layoutInflater = LayoutInflater.from(parent.context)
        val itemView = layoutInflater.inflate(R.layout.main_recycler_item,parent,false)
//        val itemView = layoutInflater.inflate(R.layout.card_item,parent,false)
        itemView.setOnClickListener{
            //点击事件
        }
        return  MyViewHold(itemView)
    }

也可以在onBindViewHolder中对控件设置点击事件

//视图解析出来之后 需不需要将数据绑定到上面
    @SuppressLint("WrongConstant")
    override fun onBindViewHolder(holder: MyViewHold, position: Int) {
        holder.iconImageView.setImageResource(imageDataSource[position])
        holder.titleView.text = if (position%2 ==0) "银河以北,吾彦最美" else "银河以南,为彦而燃"
        holder.iconImageView.setOnClickListener{
            Toast.makeText(holder.iconImageView.context,holder.titleView.text,1000).show()
        }
    }

四、运行结果

你可能感兴趣的:(RecyclerView使用攻略)