简化开发

RecyclerView-实现多布局

2020-11-03  本文已影响0人  Android砖家

在安卓开发中,随着业务的丰富,在列表数据展示中,布局多样式很常见,如下图所示:

yhx.gif

第一步:拿到UI页面之后不要慌,分析页面有几种类型展示,拿上图来说,一共四种类型。下图标记说明:

yhx.png

第二步:上代码:

class RvAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    private var liquidates = mutableListOf<DataBean>()

     //标识布局类型
    companion object {
        const val TYPE_ONE = 1
        const val TYPE_TWO = 2
        const val TYPE_THREE = 3
        const val TYPE_FOUR = 4
    }

    fun setDatas(lists: MutableList<DataBean>) {
        this.liquidates = lists
        notifyDataSetChanged()
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            TYPE_ONE -> {
                OneViewHolder((LayoutInflater.from(parent.context).inflate(R.layout.rv_item_type_one, parent, false)))
            }
            TYPE_TWO -> {
                TwoViewHodler((LayoutInflater.from(parent.context).inflate(R.layout.rv_item_type_two, parent, false)))
            }
            TYPE_THREE -> {
                ThreeViewHolder((LayoutInflater.from(parent.context).inflate(R.layout.rv_item_type_three, parent, false)))
            }
            else -> {
                FourViewHolder((LayoutInflater.from(parent.context).inflate(R.layout.rv_item_type_four, parent, false)))
            }
        }
    }

    override fun getItemCount(): Int {
        return liquidates.size
    }

   /**
     * 这个方法重要
     * 说明 根据数据源中bean中 type标识返回当前布局类型
     */
    override fun getItemViewType(position: Int): Int {

        return when (liquidates[position].type) {
            1 -> {
                TYPE_ONE
            }
            2 -> {
                TYPE_TWO
            }
            3 -> {
                TYPE_THREE
            }
            else -> {
                TYPE_FOUR
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val item = liquidates[position]
        when (holder.itemViewType) {
            TYPE_ONE -> {
                val oneViewHolder = holder as OneViewHolder
                //设置数据
                oneViewHolder.itemView.title.text = item.name

            }
            TYPE_TWO -> {
                val twoViewHodler = holder as TwoViewHodler
                //
                twoViewHodler.itemView.title.text = item.name
            }
            TYPE_THREE -> {
                val threeViewHolder = holder as ThreeViewHolder
            }

            else -> {
                val fourViewHolder = holder as FourViewHolder
            }
        }
    }


    class OneViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    }

    class TwoViewHodler(itemView: View) : RecyclerView.ViewHolder(itemView) {

    }


    class ThreeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    }

    class FourViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    }

}

第三步:MainActivity

class MainActivity : AppCompatActivity() {

    val rvAdapter by lazy {
        RvAdapter()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        val gridLayoutManager = GridLayoutManager(this, 4)
        gridLayoutManager.spanSizeLookup = mySpanSizeLookup()
        Rv.layoutManager = gridLayoutManager
        Rv.adapter = rvAdapter
        rvAdapter.setDatas(getlistDatas())
    }


    fun getlistDatas(): MutableList<DataBean> {
        val lists = mutableListOf<DataBean>()

        lists.add(DataBean("这是标题栏1>>>> 表示第一种布局类型", 1))
        lists.add(DataBean("这是内容2>>>> 表示第二种布局类型", 2))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 3))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))

        lists.add(DataBean("这是标题栏1>>>> 表示第一种布局类型", 1))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))

        lists.add(DataBean("这是标题栏1>>>> 表示第一种布局类型", 1))
        lists.add(DataBean("这是内容2>>>> 表示第二种布局类型", 2))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 3))

        lists.add(DataBean("这是标题栏1>>>> 表示第一种布局类型", 1))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))

        lists.add(DataBean("这是标题栏1>>>> 表示第一种布局类型", 1))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))
        lists.add(DataBean("这是内容3>>>> 表示第二种布局类型", 4))

        return lists
    }

    inner class mySpanSizeLookup : GridLayoutManager.SpanSizeLookup() {
        override fun getSpanSize(position: Int): Int {

            return when (getlistDatas()[position].type) {
                //当type为1,或4时,当前item布局所占权重为4份,也就是一行显示。
               //在上面我们设置了GridLayoutManager为一行显示4个item,每个item所占比为1/4。
                1,4 -> {
                    4
                }
            //以此类推,当type 2或3时,为屏幕的一半。(比重由GridLayoutManager初始值决定)
                2,3 -> {
                    2
                }
                else -> {
                    0
                }
            }
        }

    }
}

总结:RecyclerView复杂的多布局结合SpanSizeLookup使用,比较容易实现。把数据源造好,demo中,比较难理解的地方,我都给了注释说明
上一篇 下一篇

猜你喜欢

热点阅读