RecyclerView选中item居中显示

2018-08-28  本文已影响1091人  风雪守候

使用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)
    */
}

这个方法局限性比较大,遇到以下的情况也没用,比如:

1.RecyclerView的高度无法拿到
2.item的高度无法拿到
3.item的高度不固定(但是如果是能拿到每一个具体item的高度也可以去做计算)
上一篇下一篇

猜你喜欢

热点阅读