使用RecyclerView时需要将选中的item在View中居中显示,RecyclerView的scrollToPosition(position)方法只会将position所对应的item滚动到屏幕中显示,但是不会讲item居中;scrollToPosition(position)方法调用后有三种情况:
1.position对应的item在第一个可见item之前
最后会将item显示在RecyclerView的顶部
2.position对应的item在最后一个可见item之后
最后会将item显示在RecyclerView的底部
3.position对应的item已经可见
没有任何效果
如果我们需要将position对应的item居中显示怎么办?
上面的3种情况说明,直接使用scrollToPosition(position)是不行的,但是可以算出position的offset(偏移量)来使item居中显示,偏移量计算如下:
public int computePositionOffset(int position) {
int offsetPosition = 0;
int firstPosition = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0));
int lastPosition = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1));
//获取firstPosition,lastPosition的第二种方法
// LinearLayoutManager manager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
// int firstPosition = manager.findFirstVisibleItemPosition();
// int lastPosition = manager.findLastVisibleItemPosition();
//最大的position
int maxPosition = myAdapter.getItemCount() - 1;
//position的偏移量
int offset = (lastPosition - firstPosition) / 2;
if (firstPosition > position) { //第一种情况
offsetPosition = position - offset;
} else if (lastPosition < position) { //第二种情况
offsetPosition = position + offset;
} else { //第三种情况
if (lastPosition - position > position - firstPosition) {//第三种情况中position在中心点偏上
offsetPosition = position - offset;
} else {//第三种情况中position在中心点偏下
offsetPosition = position + offset;
}
}
//偏移过的offsetPosition越界
if (offsetPosition < 0) {
offsetPosition = 0;
} else if (offsetPosition > maxPosition) {
offsetPosition = maxPosition;
}
return offsetPosition;
}
使用偏移后的offsetPosition可以将目标position居中显示。
以上计算偏移量的方法有个问题
firstPosition,lastPosition在RecyclerView还没有将itemView显示之前,获取到的值是-1,这样会导致计算的偏移量不正确。
添加一个解决办法,该解决办法在一定程度下可用,但是局限性较大
LinearLayoutManager manager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
int firstPosition = manager.findFirstVisibleItemPosition();
int lastPosition = manager.findLastVisibleItemPosition();
//当获取到的firstPosition,lastPosition无效的时候,我们可以当做RecyclerView是从第0个item开始显示
if (firstPosition < 0){
firstPosition = 0;
}
if (lastPosition < 1){
lastPosition = maxItemCounts;//maxItemCounts为RecyclerView在屏幕中从第0个item开始,能显示多少个item;
/*
*比如一个比较简单且特殊的情况:
*已知RecyclerView的高度,
*所有item高度一致且已知item高度的情况下,
*maxItemCounts = Math.ceil(RecyclerViewHeight / itemHeight)
*/
}
这个方法局限性比较大,遇到以下的情况也没用,比如: