您的位置:首页 > 移动开发 > Android开发

Android RecyclerView.smoothScrollToPosition()的实现

2016-10-31 10:55 441 查看
本以为RecyclerView会像ListView一样有smoothScrollToPosition的方法,用来做双击返回列表顶部的方法,但实际添加这个方法以后并没有什么卵用,于是查看器源代码

public void smoothScrollToPosition(int position) {
if (mLayoutFrozen) {
return;
}
if (mLayout == null) {
Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. " +
"Call setLayoutManager with a non-null argument.");
return;
}
mLayout.smoothScrollToPosition(this, mState, position);
}然后继续往里点
public void smoothScrollToPosition(RecyclerView recyclerView, State state,
int position) {
Log.e(TAG, "You must override smoothScrollToPosition to support smooth scrolling");
}

SDK居然没有给出这个方法的实现,还让我们自己复写这个方法来实现,真是太坑了,于是我只能自己去复写RecyclerView的smoothScrollToPosition方法了。
下面以双击返回列表顶部为例,实现方案是这样的:

1、首先计算要滚动的距离,如果你的item元素每个都是一样高的,那么计算起来就非常简单,只需要用每个元素的高度乘现在屏幕低端是第几个就好,如果每个item的高度是不定,那么就需要依次计算相加,一般用measure()方法

2、知道要滚动的距离之后,调用smoothScrollBy方法滚动这段距离,然后滚回顶部就可以了。

现在问题来了,如果我知道要滚动的距离是多少,我还要smotthScrollToPositon这个方法干嘛,直接用smoothScrollBy不就好了。所以我们现在不需要知道每个item具体的高度是多少,只需要大概能估摸出来就行。

所以现在变成了

1、首先估摸一下大概要滚动多少距离,然后挑一个绝对会大于该滚动距离的值,使用smoothScrollBy进行滚动

2、设置onScrollListener监听滚动事件,当滚动到目标地址以后立即刹车停住。

其中估摸的滚动距离要大于实际的滚动距离,但是也不要大太多,虽然这个值只要比实际滚动距离大就可以实现滚动到指定位置,但是偏离值越大速度就越快,很可能看不清滚动效果。

代码如下,方法名是scrollUpToPosition()用来向上滚,实现双击返回列表顶部的效果

public void smoothScrollUpToPosition(final int position, int itemHeight){
int height = (layoutManager.findLastVisibleItemPositon())*itemHeight;
this.addOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);

}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstVisibleItem = layoutManager.findFirstVisibleItemPosition();//获得屏幕第一个可见元素的位置
if (firstVisibleItem == position + 1) {
smoothScrollBy(0, 0);//刹车,停止当前滚动
removeOnScrollListener(this);
}

}
});
this.smoothScrollBy(0,-height);
}

调用方法
RecyclerView.smoothScrollUpToPosition(1, getScreenHeigth()/2)其中第二个参数是每个item的估计高度,我这里估计屏幕高度的一半,这个高度要大于滚动

如果是向下滚,可以使用下面这段代码:

public void smoothScrollDownToPosition(final int position, int itemHeight){
int height = (layoutManager.findLastVisibleItemPosition())*itemHeight;
this.addOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);

}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int lastVisibleItem = layoutManager.findLastVisibleItemPosition();
if (lastVisibleItem == position + 1) {
smoothScrollBy(0, 0);
removeOnScrollListener(this);
}

}
});
this.smoothScrollBy(0,height);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: