Android开发Android技术知识Android开发经验谈

仿拼多多搜索页面多列表联动

2018-09-05  本文已影响41人  十方天仪君

项目有类似的功能,在网上找了不少都不是很符合,结合起来自己做了一个,用2个recycleview就可以解决了。
主要是右边带动左边列表滚动,先看图吧:录制的不是很流畅,可以自己下下来看看


TIM图片20180905173437.gif

1.关键代码

private fun smoothMoveToPosition() {

    mShopRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)

            if (mRightList[first].isHeader) {
                val view = mShopLinearLayoutManager.findViewByPosition(first)
                if (view != null) {
                    //如果此组名item顶部和父容器顶部距离大于等于title的高度,则设置偏移量
                    if (view.top >= tHeight) {
                        right_title.y = (view.top - tHeight).toFloat()
                    } else {
                        //否则不设置
                        right_title.y = 0f
                    }
                }
            }
            //因为每次滑动之后,右侧列表中可见的第一个item的position肯定会改变,并且右侧列表中可见的第一个item的position变换了之后,
            //才有可能改变右侧title的值,所以这个方法内的逻辑在右侧可见的第一个item的position改变之后一定会执行
            val firstPosition = mShopLinearLayoutManager.findFirstVisibleItemPosition()

            if (first != firstPosition && firstPosition >= 0) {

                //给First赋值
                first = firstPosition
                //不设置Y轴的偏移量
                right_title.y = 0f

                //判断如果右侧可见的第一个item是否是header,设置相应的值
                if (mRightList[first].isHeader) {
                    right_title.text = mRightList[first].header
                } else {
                    right_title.text = mRightList[first].t.name
                }
            }

            /**
             *遍历左边列表,列表对应的内容等于右边的title,则设置左侧对应的item高亮
             */
            mLeftList.forEachIndexed { index, s ->
                if (mLeftList[index] == right_title.text) {

                    mSearchLeftListQuickAdapter.selectItem(index)
                    moveToCenter(index)
                }
            }
            //如果右边最后一个完全显示的item的position,等于bean中最后一条数据的position(也就是右侧列表拉到底了),
            //则设置左侧列表最后一条item高亮
            if (mShopLinearLayoutManager.findLastCompletelyVisibleItemPosition() == mRightList.size - 1) {
                mSearchLeftListQuickAdapter.selectItem(mLeftList.size - 1)
                moveToCenter(mLeftList.size - 1)
            }
        }

        override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            //获取右侧title的高度
            tHeight = right_title.height
        }
    })

}
//将当前选中的item居中,如果不加这段代码,左边的recyclerview并不会跟随滚动
private fun moveToCenter(position: Int) {
    //将点击的position转换为当前屏幕上可见的item的位置以便于计算距离顶部的高度,从而进行移动居中
    val childAt = mSelectedRecyclerView.getChildAt(position - mLinearLayoutManager.findFirstVisibleItemPosition())
    if (childAt != null) {
        val y = childAt.top - mSelectedRecyclerView.height / 2
        mSelectedRecyclerView.smoothScrollBy(0, y)
    }

}

2.左边adapter里面关键代码

 fun selectItem(position: Int) {

    tv.forEachIndexed { index, _ ->
        if (position == index) {
            tv[index].setTextColor(ContextCompat.getColor(mContext, R.color.colorAccent))
            tv[index].setBackgroundColor(ContextCompat.getColor(mContext, R.color.colorPrimary))
        } else {
            tv[index].setTextColor(ContextCompat.getColor(mContext, R.color.colorPrimary))
            tv[index].setBackgroundColor(ContextCompat.getColor(mContext, R.color.colorAccent))
        }
    }
}

这里是循环添加adapter的TextView,因为如果循环的是数据的话,当你数据过多,那么就会有数组越界的问题,问题recycleview适配器一开始并没有那么加载出来那么多TextView,例如:一个屏幕只能看见12条数据,那么当你的数据超过12的时候一开始就会出错,循环tv就没有这个问题了。具体有需要的自己看代码吧。
参考:https://www.jianshu.com/p/82ced8707f2b
github:https://github.com/byning2012/RVandRv

上一篇下一篇

猜你喜欢

热点阅读