当前位置:   article > 正文

Android 自动滚动的RecyclerView,手动滑动和自动滑动无缝衔接,手动滑动时数据不重复_recyclerview无限循环后自动滚动

recyclerview无限循环后自动滚动

概要

做一个自动滑动的列表,用于展示聊天记录或者通知栏信息等,还是使用主流的RecyclerView来做。网上有很多案例,但当手动滑动时会一直无限循环,数据重复的出现,如果想要自动滑动时能无限循环,手动滑动时又能滑到底呢?本案例就解决这种手动滑动和自动滑动无缝衔接的问题。

思路

1、重写RecyclerView,通过scrollBy和postDelayed进行定时移动到达自动滑动目的

2、RecyclerView添加addOnScrollListener,进行手指按下滑动和抬起监听,用于判断是手动滑动还是自动滑动。

3、修改adapter的itemCount

4、接下来上代码

实现方案

1、重写 RecyclerView:

  1. public class SocllRecyclerView extends RecyclerView {
  2. private Autoaaview autoview;
  3. private boolean running;
  4. private boolean canrun;
  5. private static final int Timea = 40;//控制滚动的速度,值越大速度越慢
  6. public SocllRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
  7. super(context, attrs);
  8. autoview = new Autoaaview(this);
  9. }
  10. public SocllRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
  11. super(context, attrs, defStyle);
  12. }
  13. private class Autoaaview implements Runnable{
  14. WeakReference<SocllRecyclerView> myScrViewWeakReference;
  15. public Autoaaview(SocllRecyclerView myScrView) {
  16. myScrViewWeakReference = new WeakReference<>(myScrView);
  17. }
  18. @Override
  19. public void run() {
  20. SocllRecyclerView myScrView = myScrViewWeakReference.get();
  21. if (myScrView.canrun&&myScrView.running){
  22. myScrView.scrollBy(2,2);
  23. myScrView.postDelayed(myScrView.autoview,Timea);
  24. }
  25. }
  26. }
  27. //开始滚动
  28. public void start(){
  29. if (running)
  30. stop();
  31. running = true;
  32. canrun = true;
  33. postDelayed(autoview,Timea);
  34. }
  35. //停止滚动
  36. public void stop() {
  37. running = false;
  38. removeCallbacks(autoview);
  39. }
  40. @Override
  41. public boolean onTouchEvent(MotionEvent e) {
  42. return super.onTouchEvent(e);
  43. }
  44. }

2、适配器 MyscrviewAdapter

  1. public class MyscrviewAdapter extends RecyclerView.Adapter<ViewHolder> {
  2. Context context;
  3. List<NoticeBean.RecordsBean> mies;
  4. private int itemCount = Integer.MAX_VALUE;
  5. public MyscrviewAdapter(Context context, List<NoticeBean.RecordsBean> mies) {
  6. this.context = context;
  7. this.mies = mies;
  8. }
  9. public void updateAll(List<NoticeBean.RecordsBean> list) {
  10. mies.clear();
  11. mies.addAll(list);
  12. notifyDataSetChanged();
  13. }
  14. /**
  15. * 设置状态,用于设置ItemCount的数量
  16. * state:1 表示正在手指滑动,itemCount设置为实际数量;
  17. * 其他的表示结束手动滑动,itemCount设置为最大值Integer.MAX_VALUE
  18. * @param state
  19. */
  20. public void setItemCount(int state) {
  21. this.itemCount = state == 1 ? mies.size() : Integer.MAX_VALUE;
  22. notifyDataSetChanged();
  23. }
  24. @NonNull
  25. @Override
  26. public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  27. View inflate = LayoutInflater.from(context).inflate(R.layout.item_home_news, parent, false);
  28. ViewHolder baseViewHolder = new ViewHolder(inflate);
  29. return baseViewHolder;
  30. }
  31. @Override
  32. public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
  33. holder.setText(R.id.tvNewsTitle, mies.get(position % mies.size()).getTitle());
  34. holder.itemView.setOnClickListener(new View.OnClickListener() {
  35. @Override
  36. public void onClick(View v) {
  37. if (null != mItemClickListener) {
  38. mItemClickListener.onItemClick(mies.get(position % mies.size()), position);
  39. }
  40. }
  41. });
  42. }
  43. @Override
  44. public int getItemCount() {
  45. return mies.size() > 4 ? itemCount : mies.size();
  46. }
  47. //使用接口回调点击事件
  48. private ItemClickListener mItemClickListener;
  49. public void setOnItemClickListener(ItemClickListener itemClickListener) {
  50. this.mItemClickListener = itemClickListener;
  51. }
  52. public interface ItemClickListener {
  53. void onItemClick(Object obj, int position);
  54. }
  55. }

ViewHolder封装类

  1. public class ViewHolder extends RecyclerView.ViewHolder {
  2. //用于缓存已找的界面
  3. private SparseArray<View> mView;
  4. public ViewHolder(View itemView) {
  5. super(itemView);
  6. mView=new SparseArray<>();
  7. }
  8. public <T extends View> T getView(int viewId){
  9. //对已有的view做缓存
  10. View view=mView.get(viewId);
  11. //使用缓存的方式减少findViewById的次数
  12. if(view==null){
  13. view=itemView.findViewById(viewId);
  14. mView.put(viewId,view);
  15. }
  16. return (T) view;
  17. }
  18. //通用的功能进行封装 设置文本 设置条目点击事件 设置图片
  19. public ViewHolder setText(int viewId , CharSequence text){
  20. TextView view = getView(viewId);
  21. view.setText(text);
  22. //希望可以链式调用
  23. return this;
  24. }
  25. //通用的功能进行封装 设置文本 设置条目点击事件 设置图片
  26. public ViewHolder setText(int viewId , String text){
  27. TextView view = getView(viewId);
  28. view.setText(text);
  29. //希望可以链式调用
  30. return this;
  31. }
  32. public ViewHolder setSelected(int viewId ,boolean selected){
  33. TextView view = getView(viewId);
  34. view.setSelected(selected);
  35. //希望可以链式调用
  36. return this;
  37. }
  38. public ViewHolder setSelected2(int viewId,boolean selected){
  39. View view = getView(viewId);
  40. view.setSelected(selected);
  41. return this;
  42. }
  43. public ViewHolder setVisible(int viewId,boolean visible){
  44. View view = getView(viewId);
  45. view.setVisibility(visible ? View.VISIBLE : View.GONE);
  46. return this;
  47. }
  48. public ViewHolder setVisible(int viewId,boolean visible,boolean isLocation){
  49. View view = getView(viewId);
  50. if (isLocation){
  51. view.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
  52. }else{
  53. view.setVisibility(visible ? View.VISIBLE : View.GONE);
  54. }
  55. return this;
  56. }
  57. /**
  58. *设置本地图片
  59. * @param viewId
  60. * @param resId
  61. * @return
  62. */
  63. public ViewHolder setImageResource(int viewId,int resId){
  64. ImageView iv=getView(viewId);
  65. iv.setImageResource(resId);
  66. return this;
  67. }
  68. public ViewHolder setTextSelected(int viewId, boolean bool) {
  69. TextView tv = getView(viewId);
  70. tv.setSelected(bool);
  71. return this;
  72. }
  73. /**
  74. *设置本地图片
  75. * @param viewId
  76. * @param resId
  77. * @return
  78. */
  79. public ViewHolder setImageDrawable(Context mContext, int viewId, int resId){
  80. ImageView iv=getView(viewId);
  81. iv.setImageDrawable(mContext.getResources().getDrawable(resId));
  82. return this;
  83. }
  84. /**
  85. * 加载图片资源路径
  86. * @param viewId
  87. * @param imageLoader
  88. * @return
  89. */
  90. public ViewHolder setImagePath(int viewId,HolderImageLoader imageLoader,int res){
  91. ImageView iv=getView(viewId);
  92. imageLoader.loadImage(iv,imageLoader.getPath(),res);
  93. return this;
  94. }
  95. public ViewHolder setImage(Context mContext, int viewId, String url, int res) {
  96. ImageView view = getView(viewId);
  97. GlideLoadImageUtils.loadRectangleImg(mContext, view, url,res);
  98. return this;
  99. }
  100. public ViewHolder setCircleImage(Context mContext, int viewId, String url, int res) {
  101. ImageView view = getView(viewId);
  102. GlideLoadImageUtils.loadCircleImg(mContext, view, url,res);
  103. return this;
  104. }
  105. public ViewHolder setTextColor(Context mContext, int viewId, int color) {
  106. TextView tv = (TextView)this.getView(viewId);
  107. tv.setTextColor(mContext.getResources().getColor(color));
  108. return this;
  109. }
  110. public ViewHolder setTextSize(Context mContext, int viewId, float res) {
  111. TextView tv = (TextView)this.getView(viewId);
  112. tv.setTextSize(Utils.dp2px(mContext,res));
  113. return this;
  114. }
  115. @SuppressLint("NewApi")
  116. public ViewHolder setBackground(Context mContext, int viewId, int bg) {
  117. TextView tv = (TextView)this.getView(viewId);
  118. tv.setBackground(mContext.getResources().getDrawable(bg));
  119. return this;
  120. }
  121. /**
  122. * 关于事件的
  123. */
  124. public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
  125. View view = getView(viewId);
  126. view.setOnClickListener(listener);
  127. return this;
  128. }
  129. public abstract static class HolderImageLoader{
  130. public String mPath;
  131. public Context mContext;
  132. public HolderImageLoader(Context mContext, String path){
  133. this.mPath=path;
  134. this.mContext = mContext;
  135. }
  136. /**
  137. * 需要去复写这个方法加载图片
  138. * @param iv
  139. * @param path
  140. */
  141. public abstract void loadImage(ImageView iv, String path, int res);
  142. public String getPath(){
  143. return mPath;
  144. }
  145. }
  146. }

3、activity中使用

     RecyclerView滑动监听,注释都说的很详细

  1. /**
  2. * 控制通知公告数据滚动
  3. * 手指滑动时 停止自动滚动
  4. * 手指抬起时,3秒后自动开始滚动
  5. */
  6. private void initRlvNews() {
  7. scroHandler = new Handler();//定义handler
  8. runnable = () -> { //runnable方法,处理延时后的操作
  9. newsAdapter.setItemCount(0);//0表示手指已经抬起来了
  10. rlvNews.start(); //开始滑动
  11. };
  12. rlvNews.addOnScrollListener(new RecyclerView.OnScrollListener() {
  13. @Override
  14. public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
  15. super.onScrollStateChanged(recyclerView, newState);
  16. if (null != newsAdapter) {
  17. if (newState == 1) {//newState的值:1 手指按下拖拽滚动,2自动滚动(一般指惯性滚动),0 禁止没有滚动
  18. rlvNews.stop();//停止自动滚动
  19. newsAdapter.setItemCount(newState);
  20. } else {
  21. scroHandler.removeCallbacks(runnable);//清除runnable重新开始
  22. //这里设置3秒是预估了手指滑动抬起再滑动的时间,提升体验
  23. scroHandler.postDelayed(runnable, 3000);
  24. }
  25. }
  26. }
  27. });
  28. }

4、布局文件:

  需要给固定高度

  1. <com.anyi.credit.bank.view.SocllRecyclerView
  2. android:id="@+id/rlvNews"
  3. android:layout_width="match_parent"
  4. android:layout_height="144dp"/>

5、数据绑定

         rlvNews.setLayoutManager()//可设置水平滚动或竖直滚动布局

        MyscrviewAdapter adpter=new MyscrviewAdapter(this,list)

        rlvNews.setAdapter(adpter)

        //关键,条件自定义,如当列表数据大于4条时开始滑动

        if(list.size()>4){

                rlvNews.start(); //开始滑动

        }

结束------------

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/538648
推荐阅读
相关标签
  

闽ICP备14008679号