RecyclerView用法总结

203 阅读2分钟

添加依赖

implementation 'androidx.recyclerview:recyclerview:1.0.0'

创建实体类

class Msg(val content: String, val type: Int) {
    companion object{
        const val TYPE_RECEIVED = 0
        const val TYPE_SENT = 1
    }
}

准备RecyclerView的子项布局

准备适配器

  1. MsgAdapter继承自RecyclerView.Adapter,并将泛型指定为MsgAdapter.ViewHolder。
  2. ViewHolder是MsgAdapter中的内部类,继承自RecyclerView.ViewHolder(view)。这个view是RecyclerView子项最外层的布局,可以通过findViewById找到布局中的子项。
  3. MsgAdapter(private val msgList: List)主构造函数用于把要展示的数据源传进来。
  4. 必须重写的方法:
    • onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder
      
    将子项布局加载进来,并把加载出来的布局传入到构造函数中,最后返回ViewHolder实例。
    • onBindViewHolder(holder: ViewHolder, position: Int)
      
    用于对RecyclerView子项的数据进行赋值。通过position得到当前项Fruit的实例。
    • getItemCount()
      
    用于告诉RecyclerView一共有多少子项,返回数据源的长度。
  • 密封类:
sealed class MsgViewHolder(view: View): RecyclerView.ViewHolder(view)

class LeftViewHolder(view: View): MsgViewHolder(view){
   val leftMsg: TextView = view.leftMsg
}

class RightViewHolder(view: View): MsgViewHolder(view){
   val rightMsg: TextView = view.rightMsg
}
  • 适配器:
class MsgAdapter(private  val msgList: List<Msg>): RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun getItemViewType(position: Int): Int {
        val msg = msgList[position]
        return msg.type
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = if(viewType == Msg.TYPE_RECEIVED){
        val view = LayoutInflater.from(parent.context).inflate(R.layout.msg_left_item, parent, false)
        LeftViewHolder(view)
    }else{
        val view = LayoutInflater.from(parent.context).inflate(R.layout.msg_right_item, parent, false)
        RightViewHolder(view)
    }

    override fun getItemCount() = msgList.size

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val msg = msgList[position]
        when(holder){
            is LeftViewHolder -> holder.leftMsg.text = msg.content
            is RightViewHolder -> holder.rightMsg.text = msg.content
        }
    }
}
  • getItemViewType(position: Int): Int 
    
    返回当前position对应的消息类。

使用RecyclerView

  1. 初始化数据源。
    
  2. 指定RecyclerView的布局方式。
    
  3. 将数据源传入到适配器的构造函数中。
    
  4. 设置RecyclerView的适配器。
    
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager

adapter = MsgAdapter(msgList)
recyclerView.adapter = adapter
  • 运行时向RecyclerView中插入元素:
    
override fun onClick(v: View?) {
   when(v){
       send -> {
           val content = inputText.text.toString()
           if(content.isNotEmpty()) {
               val msg = Msg(content, Msg.TYPE_SENT)
               msgList.add(msg)
               //when appear a new msg, update recyclerview
               adapter.notifyItemInserted(msgList.size - 1)
               //Navigate to the latest msg
               recyclerview.scrollToPosition(msgList.size - 1)
               //clear the input content
               inputText.setText("")
           }
       }
   }
}

实现横向滚动和瀑布流布局

  1. 实现横向滚动
    
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
  1. GridLayoutManager可以用于实现网格布局,StaggeredGridLayoutManager可以用于实现瀑布流布局。
    
val layoutManager = StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)
传入3表示把布局分为3列。

RecyclerView的点击事件

将点击事件写在ViewHolder中的init结构体中。