item高度动态变化的RecyclerView

<h4>首先来看一下效果图</h4>

LinearLayoutManager.gif

GridLayoutManager.gif

<h1>解题思路</h1>
首先可以确定的是每个item肯定是有最大高度和最小高度的,所以我们先要给定item的目标高度(targetHeight)和初始高度(defaultHeight)。
</br>
就以 LinearLayoutManager和targetHeight大于defaultHeight为例,都是第一排的item往上滑动的时候item高度是减小的,但是第二排的item的高度是增加的,很明显的能看出当我们滑动的时候,列表滑动是很流畅的,不难看出第一排item高度的减小和第二排item高度的增加是守恒的,也就是说这两个高度相加是一直等于targetHeight+defaultHeight的,所有我们只需要确定了第一个item的高度那么第二个item的高度就等于targetHeight+defaultHeight-第一个item的高度。
</br>
那么第一个item的高度要怎么确定呢,理论上这个top绝对值的的最大值是defaultheight,因为当第一个item快要完全划出去的时候我们通过getTop获取到的高度就应该是defaultHeight,而且第一个item就应该根据top的变化来动态的改变自己的高度,而top绝对值变化的范围就是在targetHeight 和defaultHeight之间的,那么根据高度的变化就等于(top * 1f / defaultHeight) * (targetHeight - defaultHeight),再通过和targetHeight求和就得到了第一个item的高度了,可以看出第一个item高度的范围,当top为0的时候是targetHeight,当top为-targetHeight的时候(不难看出第一个item的top值一直是小于等于0的)是defaultHeight。

View childAt0 = getChildAt(0);
                            ViewGroup.LayoutParams layoutParams0 = childAt0.getLayoutParams();
                            int top = childAt0.getTop();
                            top = top <= -defaultHeight ? -defaultHeight : top;
                            layoutParams0.height = (int) (targetHeight + (top * 1f / defaultHeight) * (targetHeight - defaultHeight));
                            childAt0.requestLayout();

那么第二个item的高度确定的方法上面也说了,就是等于总高度减去第一个item的高度。

 View childAt1 = getChildAt(1);
                            ViewGroup.LayoutParams layoutParams1 = childAt1.getLayoutParams();
                            layoutParams1.height = defaultHeight + targetHeight - getChildAt(0).getLayoutParams().height;
                            childAt1.requestLayout();

接下来的item高度就好确定了,都是defaultHeight。

View childAt = getChildAt(i);
                            ViewGroup.LayoutParams layoutParams = childAt.getLayoutParams();
                            layoutParams.height = defaultHeight;
                            childAt.requestLayout();

<h1>还存在的问题</h1>
如果用户滑动速度比较慢,那么top的绝对值一直是小于等于defaultHeight的,但是当用户快速滑动的时候top的绝对值就会出现比defaultHeight大的情况,这个bug目前还不知道是怎么产生的(如果有大佬知道,希望大佬给点意见),所以目前先在第一个item确定高度的地方加上了

top = top <= -defaultHeight ? -defaultHeight : top;

这个判断避免出现top绝对值大于defaultHeight 的情况。

<a href="https://github.com/Monkeynessss/FreeStyleRecyclerViewDemo">github源代码链接</a>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容