美文网首页
Android RecyclerView一个一个自动滚动,无限循

Android RecyclerView一个一个自动滚动,无限循

作者: 潇妃壮壮 | 来源:发表于2018-11-08 10:23 被阅读0次


    实现效果

    运行效果

    看到这个效果,看到很多人用ViewFlipper实现,但是效果并不理想,于是我想到用RecyclerView试试。

    主要是监听recyclerView滑动,开始和暂停来控制,废话不多说,上代码。

    自定义RecyclerView

    public class AutoPollRecyclerViewextends RecyclerView {

    private static final long TIME_AUTO_POLL =16;

        private static final long TIME_AUTO_POLL_1 =2000;

        AutoPollTaskautoPollTask;

        AutoPollTask1autoPollTask1;

        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 AutoPollTaskimplements Runnable {

    private final WeakReferencemReference;

            //使用弱引用持有外部类引用->防止内存泄漏

            public AutoPollTask(AutoPollRecyclerView reference) {

    this.mReference =new WeakReference(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 AutoPollTask1implements Runnable {

    private final WeakReferencemReference;

            //使用弱引用持有外部类引用->防止内存泄漏

            public AutoPollTask1(AutoPollRecyclerView reference) {

    this.mReference =new WeakReference(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);

        }

    // 实现渐变效果

        PaintmPaint;

        private int layerId;

        private LinearGradientlinearGradient;

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

                }

    });

        }

    }


    自定义Manger控制滑动速度

    /**

    * 控制滑动速度的LinearLayoutManager

    */

    public class ScrollSpeedLinearLayoutMangerextends

            LinearLayoutManager {

    private float MILLISECONDS_PER_INCH =0.03f;

        private Contextcontxt;

        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 PointFcomputeScrollVectorForPosition(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

    public class AutoPollAdapterextends RecyclerView.Adapter {

    /**

    * 事件回调监听

    */

        private OnItemClickListeneronItemClickListener;

        private Contextcontext;

        private ListlistBeans;

        public AutoPollAdapter(Context context, List listBeans) {

    this.context = context;

            this.listBeans = listBeans;

        }

    @Override

        public ViewHolderonCreateViewHolder(ViewGroup parent, int viewType) {

    // 实例化展示的view

            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_auto_poll, parent, false);

            // 实例化viewholder

            ViewHolder viewHolder =new ViewHolder(view);

            return viewHolder;

        }

    @Override

        public void onBindViewHolder(final ViewHolder holder, final int position) {

    holder.tvName.setText(listBeans.get(position %listBeans.size()));

            holder.tvComment.setText("用户评论" + position);

        }

    @Override

        public int getItemCount() {

    //主要在这,实现无线轮播效果

    return Integer.MAX_VALUE;

        }

    public static class ViewHolderextends RecyclerView.ViewHolder {

    @BindView(R.id.simple_header)

    SimpleDraweeViewsimpleCover;

            @BindView(R.id.tv_name)

    TextViewtvName;

            @BindView(R.id.tv_comment)

    TextViewtvComment;

            public ViewHolder(View itemView) {

    super(itemView);

                ButterKnife.bind(this, itemView);

            }

    }

    /**

    * 设置回调监听

    *

        * @param listener

        */

        public void setOnItemClickListener(OnItemClickListener listener) {

    this.onItemClickListener = listener;

        }

    public interface OnItemClickListener {

    void onItemClick(int position);

        }

    }


    布局是很简单的就不贴了

    使用方法

    在Acitivity中使用

    ScrollSpeedLinearLayoutManger layoutManager =new ScrollSpeedLinearLayoutManger(this);

    layoutManager.setSmoothScrollbarEnabled(true);

    layoutManager.setAutoMeasureEnabled(true);

    recyclerView.setLayoutManager(layoutManager);// 布局管理器。

    recyclerView.setHasFixedSize(true);// 如果Item够简单,高度是确定的,打开FixSize将提高性能。

    recyclerView.setItemAnimator(new DefaultItemAnimator());// 设置Item默认动画,加也行,不加也行。

    recyclerView.setAdapter(new AutoPollAdapter(TestActivity.this, list));

    recyclerView.start();

    recyclerView.doTopGradualEffect(StringUtil.ScreenWidth(this));


    好了,到此结束,点个赞再走呗...

    欢迎大家进群探讨Android相关技术 群号:548154942 

    相关文章

      网友评论

          本文标题:Android RecyclerView一个一个自动滚动,无限循

          本文链接:https://www.haomeiwen.com/subject/jfvixqtx.html