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);