RecyclerView循环轮播和循环走马灯

    xiaoxiao2021-03-25  119

    参考 http://blog.csdn.net/timmy_zzh/article/details/53466800,原帖是横向的连续滑动的走马灯效果,为了实现逐条滚动,在原有基础上添加了一个线程任务,并改为纵向的recyclerview;结合一下代码可以用recyclerview实现类似viewpager的轮播图效果或者textview的走马灯效果,而且横竖方向可调! 禁止recyclerview的惯性,限制每次只能手动滑动一个item; 自定义RecyclerView创建滑动定时器 public class AutoPollRecyclerView extends RecyclerView { private static final long TIME_AUTO_POLL = 16; private static final long TIME_AUTO_POLL_1 = 4000; AutoPollTask autoPollTask; AutoPollTask1 autoPollTask1; private int index=0; private boolean running; //标示是否正在自动轮询 private boolean canRun;//标示是否可以自动轮询,可在不需要的是否置false private final int mTouchSlop; public AutoPollRecyclerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); // autoPollTask = new AutoPollTask(this); autoPollTask1 = new AutoPollTask1(this); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } /** * 持续滑动(走马灯) */ static class AutoPollTask implements Runnable { private final WeakReference<AutoPollRecyclerView> mReference; //使用弱引用持有外部类引用->防止内存泄漏 public AutoPollTask(AutoPollRecyclerView reference) { this.mReference = new WeakReference<AutoPollRecyclerView>(reference); } @Override public void run() { Log.e("AutoPollRecyclerView", System.currentTimeMillis()+""); AutoPollRecyclerView recyclerView = mReference.get(); if (recyclerView != null && recyclerView.running &&recyclerView.canRun) { recyclerView.scrollBy(2, 2); recyclerView.postDelayed(recyclerView.autoPollTask,recyclerView.TIME_AUTO_POLL); } } } /*** * 一次只能滑一个item(轮播图) */ static class AutoPollTask1 implements Runnable { private final WeakReference<AutoPollRecyclerView> mReference; //使用弱引用持有外部类引用->防止内存泄漏 public AutoPollTask1(AutoPollRecyclerView reference) { this.mReference = new WeakReference<AutoPollRecyclerView>(reference); } @Override public void run() { AutoPollRecyclerView recyclerView = mReference.get(); if (recyclerView != null && recyclerView.running &&recyclerView.canRun) { recyclerView .smoothScrollToPosition(++recyclerView.index); recyclerView.postDelayed(recyclerView.autoPollTask1, TIME_AUTO_POLL_1); } } } //开启:如果正在运行,先停止->再开启 public void start() { if (running) stop(); canRun = true; running = true; // postDelayed(autoPollTask,TIME_AUTO_POLL); postDelayed(autoPollTask1,TIME_AUTO_POLL_1); } public void stop(){ running = false; // removeCallbacks(autoPollTask); removeCallbacks(autoPollTask1); } //取消RecyclerView的惯性,使每次手动只能滑一个 int lastY=0; @Override public boolean dispatchTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: lastY = (int) ev.getRawY(); if (running) stop(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_OUTSIDE: int nowY = (int) ev.getRawY(); if (nowY-lastY>mTouchSlop) {//向下滑动 smoothScrollToPosition(index==0?0:--index); if (canRun) start(); return true; }else if(lastY-nowY>mTouchSlop){//向上滑动 smoothScrollToPosition(++index); if (canRun) start(); return true; } break; } return super.dispatchTouchEvent(ev); } } }
    /** * 控制滑动速度的LinearLayoutManager */ public class ScrollSpeedLinearLayoutManger extends LinearLayoutManager { private float MILLISECONDS_PER_INCH = 0.03f; private Context contxt; public ScrollSpeedLinearLayoutManger(Context context) { super(context); this.contxt = context; } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) { @Override public PointF computeScrollVectorForPosition(int targetPosition) { return ScrollSpeedLinearLayoutManger.this .computeScrollVectorForPosition(targetPosition); } //This returns the milliseconds it takes to //scroll one pixel. @Override protected float calculateSpeedPerPixel (DisplayMetrics displayMetrics) { setSpeedSlow(); return MILLISECONDS_PER_INCH / displayMetrics.density; // return 700; //返回滑动一个pixel需要多少毫秒 } }; linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); } public void setSpeedSlow() { //自己在这里用density去乘,希望不同分辨率设备上滑动速度相同 //0.3f是自己估摸的一个值,可以根据不同需求自己修改 MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 3f; } public void setSpeedFast() { MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 0.03f; } }
    重写Adapter的getItemCount方法,实现无限循环 @Override public int getItemCount() { return Integer.MAX_VALUE; }
    用法(自己结合横竖代码整合吧~~(*-*)~~): 1、横向 AutoPollRecyclerView mRecyclerView = (AutoPollRecyclerView) findViewById(R.id.rv_recycleView); List<String> list = new ArrayList<>(); for (int i = 0; i < 5; ) { list.add(" Item: " + ++i); } AutoPollAdapter adapter = new AutoPollAdapter(this, list); mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)); mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL_LIST));//分割线 mRecyclerView.setAdapter(adapter); if (true) //保证itemCount的总个数宽度超过父类布局宽度->自己处理 mRecyclerView.start(); } 2、纵向 rv_banner = (AutoPollRecyclerView) _thisFragment.findViewById(R.id.rv_banner); LinearLayoutManager layoutManager = new ScrollSpeedLinearLayoutManger(context); layoutManager.setSmoothScrollbarEnabled(true); layoutManager.setAutoMeasureEnabled(true); rv_banner.setLayoutManager(layoutManager);// 布局管理器。 rv_banner.setHasFixedSize(true);// 如果Item够简单,高度是确定的,打开FixSize将提高性能。 rv_banner.setItemAnimator(new DefaultItemAnimator());// 设置Item默认动画,加也行,不加也行。 mRecyclerView.setAdapter(new AutoPollAdapter()); mRecyclerView.start(); Android SnapHelper貌似也很适合添加进来,让轮播图更加好看,有特色,喜欢的盆友可以自己尝试下
    转载请注明原文地址: https://ju.6miu.com/read-21566.html

    最新回复(0)