Android 开发仿购物商城主页,一个RecyclerView搞定!
程序员文章站
2022-05-16 20:27:34
...
前言
相信大家对 RecyclerView 都已经非常熟悉了,日常开发中用到的地方数不胜数,尤其在加载数据展示的时候有着强大的功能,在开发 APP 主页(类似淘宝商城主页)这种效果的时候有的人可能选择 NestedScrollView 嵌套 RecyclerView ,RecyclerView + RecyclerView,可是这样会有滑动冲突的问题,而且 RecyclerView 的复用的 ViewHolder 也不能发挥出来。网上关于 RecyclerView 的文章也是一大堆,大家一搜一大堆,话不多说了,先上效果图:
在这里使用的是 BaseMultiItemQuickAdapter ,关于BaseMultiItemQuickAdapter的使用不熟悉的大家可以去 Github 上搜一下,里面有很详细的使用方法。在这里需要介绍一下 RecyclerView 的一个类 GridLayoutManager.SpanSizeLookup,该类是一个抽象类,里面包含了一个getSpanSize(int position)的抽象方法,这个方法可以动态设置RecyclerView的显示列数,他的返回值就是指定position所占的列数。详细请看代码以及注释:
//这个方法是 Adapter 里面的,重写即可
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
val manager = recyclerView.layoutManager
if (manager is GridLayoutManager) {
manager.spanSizeLookup = object :
GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
//注意:
//manager.spanCount:表示的是你的 GridLayoutManager 设置的行数
//我这里设置的8,返回manager.spanCount意思就是只显示一列,也就是 banner 显示的位置,可以理解成 8/8
//返回2:表示显示显示 4 列,同理,返回 4 表示显示 2 列
when (getItemViewType(position)) {
HomeDataBean.VIEW_BANNER -> return manager.spanCount
HomeDataBean.VIEW_ONE -> return 2
HomeDataBean.VIEW_TWO -> return 2
HomeDataBean.VIEW_THREE -> return 4
}
return 2 //默认显示 4 列
}
}
}
}
这里还有一个比较重要的地方,那就是实体类了,里面定义了几个 TYPE ,不同的 TYPE 返回表示显示不同的 Item :
companion object {
const val VIEW_BANNER = 0 //Banner
const val VIEW_ONE = 1 //文字
const val VIEW_TWO = 2 //菜单
const val VIEW_THREE = 3//图片显示
}
文章最后贴出以上全部代码:
class HomeDataBean : MultiItemEntity {
var type:Int=0
var name: String? = null
var imageUrl = 0
var bannerList: List<Int>? = null
companion object {
const val VIEW_BANNER = 0
const val VIEW_ONE = 1
const val VIEW_TWO = 2
const val VIEW_THREE = 3
}
override val itemType: Int
get() = type
}
MultipleItemQuickAdapter 完整的 Adapter:
class HomeMultipleItemAdapter(data: MutableList<HomeDataBean>) :
BaseMultiItemQuickAdapter<HomeDataBean, BaseViewHolder>(data) {
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
val manager = recyclerView.layoutManager
if (manager is GridLayoutManager) {
manager.spanSizeLookup = object :
GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
when (getItemViewType(position)) {
HomeDataBean.VIEW_BANNER -> return manager.spanCount
HomeDataBean.VIEW_ONE -> return 2
HomeDataBean.VIEW_TWO -> return 2
HomeDataBean.VIEW_THREE -> return 4
}
return 2
}
}
}
}
init {
addItemType(HomeDataBean.VIEW_BANNER, R.layout.layout_item_banner)
addItemType(HomeDataBean.VIEW_ONE, R.layout.layout_item_text)
addItemType(HomeDataBean.VIEW_TWO, R.layout.layout_item_two)
addItemType(HomeDataBean.VIEW_THREE, R.layout.layout_item_three)
}
override fun convert(holder: BaseViewHolder, item: HomeDataBean) {
when (holder.itemViewType) {
HomeDataBean.VIEW_BANNER -> initBanner(holder, item)
HomeDataBean.VIEW_ONE -> holder.setText(R.id.tvName, item.name)
HomeDataBean.VIEW_TWO -> {
holder.setText(R.id.username, item.name)
Glide.with(context).load(item.imageUrl)
.into((holder.getView<View>(R.id.icon) as CircleClickableImageView))
}
HomeDataBean.VIEW_THREE -> {
holder.setText(R.id.threeName, item.name)
Glide.with(context).load(item.imageUrl)
.into((holder.getView<View>(R.id.icon1) as RoundRectImageView))
}
}
}
private fun initBanner(helper: BaseViewHolder?, item: HomeDataBean?) {
val banner = helper?.getView<Banner<*, *>>(R.id.banner)
val adapter = BannerImageAdapter(item?.bannerList)
banner?.let {
it.indicator = CircleIndicator(this.context)
it.setBannerRound(20f)
it.adapter = adapter
}
}
}
以上就是我想分享给大家的全部代码,希望能帮到有需要的朋友,本人也是一直在学习,若有写的不对的地方,欢迎大家指正,在评论区告诉我吧,谢谢大家!