RecyclerView滚动指定条目并在页面中居中

内容提要

本次的需求是通过指定position来控制条目滚动,并且要滚动到指定到中间的位置。

下面先上图,看看是不是你要



如下介绍主要的步骤

带着问题去做需求是一个很不错的方式:

1.我们要滚动条目?怎么滚动呢?

2.滚动到指定的position是很容易,但是条目并没有到指定准确的位置,怎么办呢?

上面的两个问题解决了,我们的需求就完成了。

下面先解决第一个问题

这个很简单了,我就一笔带过好了啊。
recyclerView.scrollToPosition(trim);
你没看错就是这个方法。(手动滑稽)

然后是第二个问题


上图中的标号请无视。
这里要计算了,首先我们要先确定条目的位置,其次是将该条目移动到中间的位置。

将条目1,移动到箭头所在位置。


view1.getX();获取view1的x坐标(黄色到第一个蓝色的距离),获取view的宽度的一半(蓝色到绿色的距离),然后在获取外层view的宽度(我这是直接填充的屏幕宽度,黄色到第二个蓝色的距离),然后计算出view1需要移动的x距离。如下:
recyclerView.smoothScrollBy(changeX - (width - childWidth), 0);
计算看着比较简单,但是实际却需要做很多限制。以下注意事项:


1.首先RecyclerView的条目是要复用的,所以实际的view数目是屏幕上显示的,再多缓存一个或者两个view(可以通过getChildCount()方法获取数量),所以计算RecyclerView条目的时候要注意不要取到屏幕外的view,会造成空指针。


2.其次就是要注意position是否大于了缓存的view数目,如果大于我们就取最大的view角标;并且我们还要区分前后滚动,因为如果大于缓存的view数向后滚动就是就是取最大的view角标,如果小于缓存的view数向后滚动的话就直接取position作为角标的view了。

上面写的有点难懂,下面直接上代码,
if (trim > recyclerView.getChildCount() - 1) { if (oldInt > trim) { childAt =
recyclerView.getChildAt(0); } else { childAt =
recyclerView.getChildAt(recyclerView.getChildCount() -1); } } else { if (oldInt
> trim) { childAt = recyclerView.getChildAt(0); } else { childAt =
recyclerView.getChildAt(trim); } }
结合代码看会比较容易。

遗留的问题


基本上处理好上面两个问题就可以达到我们的需求了,但是这里还有一个遗留的问题,就是关于界面显示的view数目和RecycledViewPool中view数目的关系。这里我是实验发现一般都会缓存一个view。所以在上面调用getChildAt()减去了1的,防止越界出现获取到空view的情况。

放出关键的代码部分,如果需要可以去文末下载demo
final int width = rect.right / 2; //角标数,不能大于页面最大的数目 final Integer trim =
Integer.parseInt(ed.getText().toString().trim());
recyclerView.scrollToPosition(trim); mHandler.postDelayed(new Runnable() {
@Override public void run() { if (trim > recyclerView.getChildCount() - 1) { if
(oldInt > trim) { childAt = recyclerView.getChildAt(0); } else { childAt =
recyclerView.getChildAt(recyclerView.getChildCount() -1); } } else { if (oldInt
> trim) { childAt = recyclerView.getChildAt(0); } else { childAt =
recyclerView.getChildAt(trim); } } changeX = (int) childAt.getX(); childWidth =
childAt.getMeasuredWidth() /2; Log.d("x", changeX + "--" +
recyclerView.getChildCount()); recyclerView.smoothScrollBy(changeX - (width -
childWidth),0); } }, 50); mHandler.postDelayed(new Runnable() { @Override public
void run() { oldInt = trim; } }, 100);
finish

虽然需求看着很简单,但是涉及到的知识点还是很好,应该了解一下。

下载demo点这里 <https://download.csdn.net/download/shayubuhuifei/10578796>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信