首先使用的是自定义的RecyclerView ,AutoPollRecyclerView继承自RecyclerView,使用recyclerView.smoothScrollBy(0,250);
来控制滑动的高度
public class AutoPollRecyclerView extends RecyclerView { private static final long TIME_AUTO_POLL = 16; private static final long TIME_AUTO_POLL_1 =8000; 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(); } public void setCanRun(boolean canRun) { this.canRun = canRun; } public void setAdapter(CallShowActivity mainActivity, List<CallShowBean.DataBean> mdate, boolean b) { } /** * 持续滑动(走马灯) */ static class AutoPollTask implements Runnable { private final WeakReference mReference; //使用弱引用持有外部类引用->防止内存泄漏 public AutoPollTask(AutoPollRecyclerView reference) { this.mReference = new WeakReference(reference); } @Override public void run() { Log.e("AutoPollRecyclerView", System.currentTimeMillis() + ""); AutoPollRecyclerView recyclerView = (AutoPollRecyclerView) mReference.get(); if (recyclerView != null && recyclerView.running && recyclerView.canRun) { recyclerView.postDelayed(recyclerView.autoPollTask, recyclerView.TIME_AUTO_POLL); } } } /*** * 一次只能滑一个item(轮播图) */ static class AutoPollTask1 implements Runnable { private final WeakReference mReference; //使用弱引用持有外部类引用->防止内存泄漏 public AutoPollTask1(AutoPollRecyclerView reference) { this.mReference = new WeakReference(reference); } @Override public void run() { AutoPollRecyclerView recyclerView = (AutoPollRecyclerView) mReference.get(); if (recyclerView != null && recyclerView.running && recyclerView.canRun) { // recyclerView.smoothScrollToPosition(++recyclerView.index); recyclerView.smoothScrollBy(0,250); 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); } // 实现渐变效果 Paint mPaint; private int layerId; private LinearGradient linearGradient; private int preWidth = 0;// Recyclerview宽度动态变化时,监听每一次的宽度 public void doTopGradualEffect(final int itemViewWidth) { mPaint = new Paint(); // dst_in 模式,实现底层透明度随上层透明度进行同步显示(即上层为透明时,下层就透明,并不是上层覆盖下层) final Xfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN); mPaint.setXfermode(xfermode); addItemDecoration(new RecyclerView.ItemDecoration() { @Override public void onDrawOver(Canvas canvas, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(canvas, parent, state); // 当linearGradient为空即第一次绘制 或 Recyclerview宽度发生改变时,重新计算透明位置 if (linearGradient == null || preWidth != parent.getWidth()) { // 透明位置从最后一个 itemView 的一半处到 Recyclerview 的最右边 linearGradient = new LinearGradient(parent.getWidth() - (itemViewWidth / 2), 0.0f, parent.getWidth(), 0.0f, new int[]{Color.BLACK, 0}, null, Shader.TileMode.CLAMP); preWidth = parent.getWidth(); } mPaint.setXfermode(xfermode); mPaint.setShader(linearGradient); canvas.drawRect(0.0f, 0.0f, parent.getRight(), parent.getBottom(), mPaint); mPaint.setXfermode(null); canvas.restoreToCount(layerId); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); // 此处 Paint的参数这里传的null, 在传入 mPaint 时会出现第一次打开黑屏闪现的问题 // 注意 saveLayer 不能省也不能移动到onDrawOver方法里 layerId = c.saveLayer(0.0f, 0.0f, (float) parent.getWidth(), (float) parent.getHeight(), null, Canvas.ALL_SAVE_FLAG); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { // 该方法作用自行百度 super.getItemOffsets(outRect, view, parent, state); } }); } }
2 修改适配器:
public class PdjhzslistAdapter extends RecyclerView.Adapter{ private OnItemClickListener onItemClickListener; private Context context; private List<CallShowBean.DataBean> listBeans; private boolean bool; HashMap map = new HashMap<String, String>(); public PdjhzslistAdapter(Context context, List<CallShowBean.DataBean> listBeans, boolean bool) { this.context = context; this.bool = bool; this.listBeans = listBeans; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // 实例化展示的view View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_pdjh, parent, false); // 实例化viewholder RecyclerView.ViewHolder viewHolder=new ViewHolder(view); return viewHolder; } //设置值 @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { CallShowBean.DataBean lockBean= listBeans.get(position % listBeans.size()); ((ViewHolder) holder).itdhrs.setText(lockBean.getCount()); } @Override public int getItemCount() { //主要在这,实现无线轮播效果 if (bool) { return Integer.MAX_VALUE; } else { return listBeans.size(); } } //和界面建立对应关系 public static class ViewHolder extends RecyclerView.ViewHolder { TextView itdhrs; public ViewHolder(View itemView) { super(itemView); itdhrs=itemView.findViewById(R.id.itdhrs); } } /** * 设置回调监听 * <p> * * @param listener * <p> * */ public void setOnItemClickListener(OnItemClickListener listener) { this.onItemClickListener = listener; } public interface OnItemClickListener { void onItemClick(int position); } }
3.自定义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; } }
5.最后Activity调用
ScrollSpeedLinearLayoutManger layoutManager1 = new ScrollSpeedLinearLayoutManger(this); layoutManager1.setSmoothScrollbarEnabled(true); layoutManager1.setAutoMeasureEnabled(true); pdzslistView.setLayoutManager(layoutManager1);// 布局管理器。
pdzslistView.setHasFixedSize(true);// 如果Item够简单,高度是确定的,打开FixSize将提高性能。 pdzslistView.setItemAnimator(new DefaultItemAnimator());// 设置Item默认动画,加也行,不加也行。 if (pdList.size() >8) { pdzslistView.setAdapter(new PdjhzslistAdapter(this, pdList, true)); pdzslistView.start(); } else { pdzslistView.setAdapter(new PdjhzslistAdapter(this, pdList, false)); }