GridLayoutManager 实现 复杂列布局

GridLayoutManager 实现 复杂列布局

最近做直播页面有个需求 直接上页面

竖直往下依次有四个ItemView 。 Item2 Item4数目依次不定 。 其中item2 数据和item4 相同 也就是整个页面同一个接口 第一次我用 2个recyclerview LinearLayoutManager Vertical .显示。

当然 大家知道 会存在item2 数据多而 item4 不能显示的情况。 用scrollview 括起来 发现无用。果然还和listview 一样。 解决办法:

  • 在每个RecyclerView外层嵌套一个RelativeLayout,并设置descendantFocusability属性。代码如下
<RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:descendantFocusability="blocksDescendants">
                <android.support.v7.widget.RecyclerView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:nestedScrollingEnabled="false">
                </android.support.v7.widget.RecyclerView>

            </RelativeLayout>
复制代码

果然数据正常显示了 但是发现滑动卡顿。 本人都体验差 肯定不行

  • 换瀑布流解决方案 StaggeredGridLayoutManager 假如 StaggeredGridLayoutManager 瀑布流 这样的图片水平显示不就是我要的效果吗。 然后经过尝试发现不行 。它控制列的变化不太灵活。

回过头再去google 查资料发现 gridlayoutmanager 可以很灵活的修改列数 。哎呀 这就对了 以前产生误解 还是理解的不太透彻 一直以为gridlayoutmanager 就是 九宫格之类的职能 有时间一定要好好再研究源码。 果然效果立马实现。

class LiveFollowAdapter(private val context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {


    //todo  重构:1命名 2数据list 管理 3泛型 4 基类提取 5viewhold 分装
    private var openRoomList: List<NAnchor> = ArrayList()
    private var closeRoomList: List<NAnchor> = ArrayList()
    private var dataList: MutableList<NAnchor> = mutableListOf()
    private val TAG = "LiveFollowAdapter"


    fun setDataList(data: NLiveFollow) {
        if (data?.closeRooms != null) {
//            openRoomList = data?.openRooms
            openRoomList = data?.closeRooms
        }
        if (data?.closeRooms != null) {
            closeRoomList = data?.closeRooms
        }

        dataList.clear()
        dataList.add(NAnchor("live_header"))
        dataList.addAll(openRoomList)
        dataList.add(NAnchor("unlive_header"))
        dataList.addAll(closeRoomList)
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            ViewType.ViewType1.ordinal -> ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_living_follow_header, parent, false))
            ViewType.ViewType2.ordinal -> ViewHolder2(LayoutInflater.from(context).inflate(R.layout.item_live_follow_grid, parent, false))
            ViewType.ViewType3.ordinal -> ViewHolder3(LayoutInflater.from(context).inflate(R.layout.item_unlive_follow_header, parent, false))
            ViewType.ViewType4.ordinal -> ViewHolder4(LayoutInflater.from(context).inflate(R.layout.item_live_follow_content, parent, false))
            else -> throw IllegalArgumentException(" holder error")
        }


    }

    override fun getItemViewType(position: Int): Int {
        if (position == 0) {
            return ViewType.ViewType1.ordinal
        } else if (position > 0 && openRoomList!!.size > 0 && position <= openRoomList.size) {
            return ViewType.ViewType2.ordinal
        } else if (position == openRoomList?.size + 1) {
            return ViewType.ViewType3.ordinal
        } else {
            return ViewType.ViewType4.ordinal
        }

    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder.itemViewType) {
            ViewType.ViewType1.ordinal -> {
                var viewHolder1 = holder as ViewHolder
                viewHolder1.bind(openRoomList.size)
            }
            ViewType.ViewType2.ordinal -> {
                var viewHolder2 = holder as ViewHolder2

                if (openRoomList.size > 0 && openRoomList.size == position && openRoomList.size % 2 != 0) {
                    viewHolder2.bind(dataList.get(position), true)
                } else {
                    viewHolder2.bind(dataList.get(position), false)
                }


            }
            ViewType.ViewType3.ordinal -> {
                var viewHolder3 = holder as ViewHolder3
                viewHolder3.bind(closeRoomList.size)
            }
            ViewType.ViewType4.ordinal -> {
                var viewHolder4 = holder as ViewHolder4
                viewHolder4.bind(dataList.get(position))
            }
        }
    }

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

    fun remove(position: Int) {
//        dataList.removeAt(position)
        notifyItemRemoved(position)
    }

    fun add(text: String, position: Int) {
//        dataList.add(position, text)
        notifyItemInserted(position)
    }
    
    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var num = itemView.findViewById<TextView>(R.id.tv_living_num)
        fun bind(size: Int) {
            num.text = "$size"
        }
    }

    class ViewHolder2(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var title = itemView.findViewById<TextView>(R.id.tv_live_anchor_title)
        var ivAvatar = itemView.findViewById<ImageView>(R.id.iv_avatar)
        var constraintLayout = itemView.findViewById<ConstraintLayout>(R.id.cl_layout)
        fun bind(anchor: NAnchor, flag: Boolean) {
            title.text = anchor?.user?.nickname
//            view.tv_anchor_motto.text = anchor.description

            GlideApp.with(itemView.context).load(anchor?.user?.avatar)
                    .placeholder(R.mipmap.iv_default_head)
                    .error(R.mipmap.iv_default_head)
                    .into(ivAvatar)
            //奇数时候 改动最后一个view
            if (flag) {
                var param: RecyclerView.LayoutParams = itemView.layoutParams as RecyclerView.LayoutParams
                val height = param.height
                val width = param.width
                param.width = height
                param.height = param.height
                itemView.visibility = View.VISIBLE
                itemView.setLayoutParams(param)
            }
        }
    }

    class ViewHolder3(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var num = itemView.findViewById<TextView>(R.id.tv_un_live_num)
        fun bind(size: Int) {
            num.text = "$size"
        }
    }

    class ViewHolder4(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var name = itemView.findViewById<TextView>(R.id.tv_un_live_name)
        var num = itemView.findViewById<TextView>(R.id.tv_un_live_follow_num)
        var civHead = itemView.findViewById<ImageView>(R.id.civ_head)
        //        var header = itemView.findViewById<ImageView>(R.id.civ_head)
        fun bind(anchor: NAnchor) {
            name.text = anchor.user.nickname
            num.text = anchor.likeCount.toString()
            GlideApp.with(itemView.context).load(anchor?.user?.avatar)
                    .placeholder(R.mipmap.iv_default_head)
                    .error(R.mipmap.iv_default_head)
                    .into(civHead)
        }
    }

    enum class ViewType {
        ViewType1, ViewType2, ViewType3, ViewType4
    }

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
        super.onAttachedToRecyclerView(recyclerView)
        val layoutManager = recyclerView.layoutManager
        if (layoutManager is GridLayoutManager) {
            layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
                override fun getSpanSize(position: Int): Int {
                    //取多个item的每行占用个数的最小公倍数,
                    //这里最小公倍数为2  只有item2  显示2行所以返回1  其余为2
                    //他们对应的return 3,return 2,return 6
                    /*2122*/
                    var viewType = getItemViewType(position)
                    return when (viewType) {
                        ViewType.ViewType1.ordinal -> 2
                        ViewType.ViewType2.ordinal -> 1
                        ViewType.ViewType3.ordinal -> 2
                        else -> 2
                    }
                }
            }
        }
    }
}

复制代码

上面onAttachedToRecyclerView 方法 是在recyclerview 与 adapter 适配数据时候 调用的 这才是关键方法 再一次见识了 recyclerview 的无比强大! Fragment 中代码 就比较简单了。

val layoutManager = GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, false);
        rv_live_follow.layoutManager = layoutManager
        liveFollowAdapter = LiveFollowAdapter(context!!)
        rv_live_follow.addItemDecoration(GridSpacingItemDecoration(DensityUtil.dip2px(context!!, 9f)))
        rv_live_follow.adapter = liveFollowAdapter
复制代码

功能催的比较紧张 代码感觉还需要重构...

大功告成 搞定收工 又是一周结束了......

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值