居中Item两边各显示一部分

1、ViewPager:实现

        //绘制超过其区域的部分
        pager.setClipToPadding(false);
        pager.setPadding(100, 0, 100, 0);
        pager.setPageMargin(50);

是ViewPager时候,那么第一条数据居中时候,左边会留空,效果不是特别好, 可以通过动态设置  pager.setPadding(12, 0, 100, 0);实现,但是效果不是特别好。

2、RecyclerView:

①、通过LinearLayoutManager实现

public class CenterLayoutManager extends LinearLayoutManager {
    private RecyclerView.SmoothScroller smoothScroller;
    public CenterLayoutManager(Context context) {
        super(context);
    }

    public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

    private static class CenterSmoothScroller extends LinearSmoothScroller {

        CenterSmoothScroller(Context context) {
            super(context);
        }

        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }
    }
}

可以通过点击设置选中居中,但是滑动RecyclerView,没法控制当前居中显示。

②、通过SnapHelper(LinearSnapHelper,滑动效果)

LinearSnapHelper linearSnapHelper = new LinearSnapHelper();
linearSnapHelper.attachToRecyclerView(reyclerView);

可以实现滑动居中显示,但是没有ViewPager那种滑动页数效果。

③、通过SnapHelper(PagerSnapHelper,类似ViewPager效果)

 PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
 pagerSnapHelper.attachToRecyclerView(recyclerView);

由于整个屏幕显示三个RecyclerView item,所以点击下一个时,我们并不知道当前显示居中item position,所以我们需要监听RecyclerView滑动事件,来获取当前居中显示position。

问题1:当总数据超过3条数据,如果获取滑动后,居中显示数据 position;

问题2:当总数据为2条时候,如果判断是第一条数据居中,还是第二条数据居中;

具体处理逻辑代码如下:

  recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == 0) {
                    //滑动停止,获取当前第一显示position和最后一个显示position
                    int firstPosition = layoutManager.findFirstVisibleItemPosition();
                    int lastPosition = layoutManager.findLastVisibleItemPosition();
                    //一屏最多展示3条数据
                    if (lastPosition - firstPosition == 2) {
                        //当前显示为3条数据,则中间position为居中item
                        centerPosition = firstPosition + 1;
                    } else if (lastPosition - firstPosition == 1) {
                        //当前显示2条数据,此时我们并不知道,显示第一条数据,还是最后一条数据局
                        //那么我们获取当前firstPosition显示View,来计算距离屏幕左边距离,通过距离值,来判断是第一条数据还是最后一条数据,居中显示了。
                        View viewByPosition = layoutManager.findViewByPosition(firstPosition);
                        if (viewByPosition != null) {
                            if (Math.abs(viewByPosition.getX()) <= (Utils.dp2px(getContext(), 12) + 20)) {
                                //firstPositionView距离屏幕距离小于间距,则第一条数据居中
                                centerPosition = firstPosition;
                            } else {
                                centerPosition = lastPosition;
                            }
                        }
                    }
                  
                }
            }
        });

问题:

1、动态设置position居中问题:

当使用PagerSnapHelper时候,我们再获取服务端返回数据,又要无法动态设置固定item居中,所以我们需要结合CenterLayoutManager 一起使用,具体伪代码如下:

     adapter.setData();
      recycler.postDelayed(new Runnable() {
             @Override
             public void run() {
                    //或者点击时候切换到置顶position,居中,可以直接调用该代码
                    if (centerLayoutManager != null && recycler != null)
                            centerLayoutManager.smoothScrollToPosition(recycler, new RecyclerView.State(), showCenterPosition);
                    }
       },300);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值