首先自定义 AutoPollRecyclerView 继承 recyclerview
public class AutoPollRecyclerView extends RecyclerView { private static final long TIME_AUTO_POLL = 100; AutoPollTask autoPollTask; private boolean running; //标示是否正在自动轮询 private boolean canRun;//标示是否可以自动轮询,可在不需要的是否置false public AutoPollRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); autoPollTask = new AutoPollTask(this); } static class AutoPollTask implements Runnable { private final WeakReference<AutoPollRecyclerView> mReference; //使用弱引用持有外部类引用->防止内存泄漏 public AutoPollTask(AutoPollRecyclerView reference) { this.mReference = new WeakReference<AutoPollRecyclerView>(reference); } @Override public void run() { AutoPollRecyclerView recyclerView = mReference.get(); if (recyclerView != null && recyclerView.running && recyclerView.canRun) { recyclerView.smoothScrollBy(50, 0, new LinearInterpolator()); recyclerView.postDelayed(recyclerView.autoPollTask, recyclerView.TIME_AUTO_POLL); } } } //开启:如果正在运行,先停止->再开启 public void start() { if (running) stop(); canRun = true; running = true; postDelayed(autoPollTask, TIME_AUTO_POLL); } public void stop() { running = false; removeCallbacks(autoPollTask); } @Override public boolean onTouchEvent(MotionEvent e) { switch (e.getAction()) { case MotionEvent.ACTION_DOWN: if (running) stop(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_OUTSIDE: if (canRun){ start(); } break; } return super.onTouchEvent(e); } }
xml 中使用
<com.example.test2recyclerviewbgimg.AutoPollRecyclerView android:layout_width="match_parent" android:layout_height="300dp" android:id="@+id/rv"/>
还有个 GallerySnaphelper 类
public class GallerySnapHelper extends SnapHelper { private static final float INVALID_DISTANCE = 1f; private static final float MILLISECONDS_PER_INCH = 40f; private OrientationHelper mHorizontalHelper; private RecyclerView mRecyclerView; @Override public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException { mRecyclerView = recyclerView; super.attachToRecyclerView(recyclerView); } @Override public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) { int[] out = new int[2]; if (layoutManager.canScrollHorizontally()) { out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager)); } else { out[0] = 0; } return out; } private int distanceToStart(View targetView, OrientationHelper helper) { return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding(); } @Nullable protected LinearSmoothScroller createSnapScroller(final RecyclerView.LayoutManager layoutManager) { if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) { return null; } return new LinearSmoothScroller(mRecyclerView.getContext()) { @Override protected void onTargetFound(View targetView, RecyclerView.State state, Action action) { int[] snapDistances = calculateDistanceToFinalSnap(mRecyclerView.getLayoutManager(), targetView); final int dx = snapDistances[0]; final int dy = snapDistances[1]; final int time = calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy))); if (time > 0) { action.update(dx, dy, time, mDecelerateInterpolator); } } @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; } }; } @Override public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) { if (!(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider)) { return RecyclerView.NO_POSITION; } final int itemCount = layoutManager.getItemCount(); if (itemCount == 0) { return RecyclerView.NO_POSITION; } final View currentView = findSnapView(layoutManager); if (currentView == null) { return RecyclerView.NO_POSITION; } final int currentPosition = layoutManager.getPosition(currentView); if (currentPosition == RecyclerView.NO_POSITION) { return RecyclerView.NO_POSITION; } RecyclerView.SmoothScroller.ScrollVectorProvider vectorProvider = (RecyclerView.SmoothScroller.ScrollVectorProvider) layoutManager; // deltaJumps sign comes from the velocity which may not match the order of children in // the LayoutManager. To overcome this, we ask for a vector from the LayoutManager to // get the direction. PointF vectorForEnd = vectorProvider.computeScrollVectorForPosition(itemCount - 1); if (vectorForEnd == null) { // cannot get a vector for the given position. return RecyclerView.NO_POSITION; } //在松手之后,列表最多只能滚多一屏的item数 int deltaThreshold = layoutManager.getWidth() / getHorizontalHelper(layoutManager).getDecoratedMeasurement(currentView); int hDeltaJump; if (layoutManager.canScrollHorizontally()) { hDeltaJump = estimateNextPositionDiffForFling(layoutManager, getHorizontalHelper(layoutManager), velocityX, 0); if (hDeltaJump > deltaThreshold) { hDeltaJump = deltaThreshold; } if (hDeltaJump < -deltaThreshold) { hDeltaJump = -deltaThreshold; } if (vectorForEnd.x < 0) { hDeltaJump = -hDeltaJump; } } else { hDeltaJump = 0; } if (hDeltaJump == 0) { return RecyclerView.NO_POSITION; } int targetPos = currentPosition + hDeltaJump; if (targetPos < 0) { targetPos = 0; } if (targetPos >= itemCount) { targetPos = itemCount - 1; } return targetPos; } @Override public View findSnapView(RecyclerView.LayoutManager layoutManager) { return findStartView(layoutManager, getHorizontalHelper(layoutManager)); } private View findStartView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) { if (layoutManager instanceof LinearLayoutManager) { int firstChildPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); if (firstChildPosition == RecyclerView.NO_POSITION) { return null; } if (((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition() == layoutManager.getItemCount() - 1) { return null; } View firstChildView = layoutManager.findViewByPosition(firstChildPosition); if (helper.getDecoratedEnd(firstChildView) >= helper.getDecoratedMeasurement(firstChildView) / 2 && helper.getDecoratedEnd(firstChildView) > 0) { return firstChildView; } else { return layoutManager.findViewByPosition(firstChildPosition + 1); } } else { return null; } } private int estimateNextPositionDiffForFling(RecyclerView.LayoutManager layoutManager, OrientationHelper helper, int velocityX, int velocityY) { int[] distances = calculateScrollDistance(velocityX, velocityY); float distancePerChild = computeDistancePerChild(layoutManager, helper); if (distancePerChild <= 0) { return 0; } int distance = distances[0]; if (distance > 0) { return (int) Math.floor(distance / distancePerChild); } else { return (int) Math.ceil(distance / distancePerChild); } } private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) { View minPosView = null; View maxPosView = null; int minPos = Integer.MAX_VALUE; int maxPos = Integer.MIN_VALUE; int childCount = layoutManager.getChildCount(); if (childCount == 0) { return INVALID_DISTANCE; } for (int i = 0; i < childCount; i++) { View child = layoutManager.getChildAt(i); final int pos = layoutManager.getPosition(child); if (pos == RecyclerView.NO_POSITION) { continue; } if (pos < minPos) { minPos = pos; minPosView = child; } if (pos > maxPos) { maxPos = pos; maxPosView = child; } } if (minPosView == null || maxPosView == null) { return INVALID_DISTANCE; } int start = Math.min(helper.getDecoratedStart(minPosView), helper.getDecoratedStart(maxPosView)); int end = Math.max(helper.getDecoratedEnd(minPosView), helper.getDecoratedEnd(maxPosView)); int distance = end - start; if (distance == 0) { return INVALID_DISTANCE; } return 1f * distance / ((maxPos - minPos) + 1); } private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) { if (mHorizontalHelper == null) { mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager); } return mHorizontalHelper; } }
在MainActivity 使用
private AutoPollRecyclerView rv;
rv=findViewById(R.id.rv);
List<String> list=new ArrayList<>(); list.add("111111111"); list.add("22222222"); list.add("3333333333"); list.add("4444444"); list.add("5555555555"); list.add("6666666"); for (int i=0;i<3;i++){ list.addAll(list); }
LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); rv.setLayoutManager(layoutManager); MYadapter mYadapter = new MYadapter(list, this); rv.setAdapter(mYadapter); new GallerySnapHelper().attachToRecyclerView(rv); // rv.start();
就此完成了整个需求