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

概要

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

思路

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

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

3、修改adapter的itemCount

4、接下来上代码

实现方案

1、重写 RecyclerView:

public class SocllRecyclerView extends RecyclerView {private Autoaaview autoview;private boolean running;private boolean canrun;private static final int Timea = 40;//控制滚动的速度,值越大速度越慢public SocllRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);autoview = new Autoaaview(this);}public SocllRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}private class Autoaaview implements Runnable{WeakReference<SocllRecyclerView> myScrViewWeakReference;public Autoaaview(SocllRecyclerView myScrView) {myScrViewWeakReference = new WeakReference<>(myScrView);}@Overridepublic void run() {SocllRecyclerView myScrView = myScrViewWeakReference.get();if (myScrView.canrun&&myScrView.running){myScrView.scrollBy(2,2);myScrView.postDelayed(myScrView.autoview,Timea);}}}//开始滚动public void start(){if (running)stop();running = true;canrun = true;postDelayed(autoview,Timea);}//停止滚动public void stop() {running = false;removeCallbacks(autoview);}@Overridepublic boolean onTouchEvent(MotionEvent e) {return super.onTouchEvent(e);}
}

2、适配器 MyscrviewAdapter

public class MyscrviewAdapter extends RecyclerView.Adapter<ViewHolder> {Context context;List<NoticeBean.RecordsBean> mies;private int itemCount = Integer.MAX_VALUE;public MyscrviewAdapter(Context context, List<NoticeBean.RecordsBean> mies) {this.context = context;this.mies = mies;}public void updateAll(List<NoticeBean.RecordsBean> list) {mies.clear();mies.addAll(list);notifyDataSetChanged();}/*** 设置状态,用于设置ItemCount的数量* state:1 表示正在手指滑动,itemCount设置为实际数量;* 其他的表示结束手动滑动,itemCount设置为最大值Integer.MAX_VALUE* @param state*/public void setItemCount(int state) {this.itemCount = state == 1 ? mies.size() : Integer.MAX_VALUE;notifyDataSetChanged();}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View inflate = LayoutInflater.from(context).inflate(R.layout.item_home_news, parent, false);ViewHolder baseViewHolder = new ViewHolder(inflate);return baseViewHolder;}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, final int position) {holder.setText(R.id.tvNewsTitle, mies.get(position % mies.size()).getTitle());holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (null != mItemClickListener) {mItemClickListener.onItemClick(mies.get(position % mies.size()), position);}}});}@Overridepublic int getItemCount() {return mies.size() > 4 ? itemCount : mies.size();}//使用接口回调点击事件private ItemClickListener mItemClickListener;public void setOnItemClickListener(ItemClickListener itemClickListener) {this.mItemClickListener = itemClickListener;}public interface ItemClickListener {void onItemClick(Object obj, int position);}
}

ViewHolder封装类

public class ViewHolder extends RecyclerView.ViewHolder {//用于缓存已找的界面private SparseArray<View> mView;public ViewHolder(View itemView) {super(itemView);mView=new SparseArray<>();}public <T extends View> T getView(int viewId){//对已有的view做缓存View view=mView.get(viewId);//使用缓存的方式减少findViewById的次数if(view==null){view=itemView.findViewById(viewId);mView.put(viewId,view);}return (T) view;}//通用的功能进行封装  设置文本 设置条目点击事件  设置图片public ViewHolder setText(int viewId , CharSequence text){TextView view = getView(viewId);view.setText(text);//希望可以链式调用return this;}//通用的功能进行封装  设置文本 设置条目点击事件  设置图片public ViewHolder setText(int viewId , String text){TextView view = getView(viewId);view.setText(text);//希望可以链式调用return this;}public ViewHolder setSelected(int viewId ,boolean selected){TextView view = getView(viewId);view.setSelected(selected);//希望可以链式调用return this;}public ViewHolder setSelected2(int viewId,boolean selected){View view = getView(viewId);view.setSelected(selected);return this;}public ViewHolder setVisible(int viewId,boolean visible){View view = getView(viewId);view.setVisibility(visible ? View.VISIBLE : View.GONE);return this;}public ViewHolder setVisible(int viewId,boolean visible,boolean isLocation){View view = getView(viewId);if (isLocation){view.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);}else{view.setVisibility(visible ? View.VISIBLE : View.GONE);}return this;}/***设置本地图片* @param viewId* @param resId* @return*/public ViewHolder setImageResource(int viewId,int resId){ImageView iv=getView(viewId);iv.setImageResource(resId);return this;}public ViewHolder setTextSelected(int viewId, boolean bool) {TextView tv = getView(viewId);tv.setSelected(bool);return this;}/***设置本地图片* @param viewId* @param resId* @return*/public ViewHolder setImageDrawable(Context mContext, int viewId, int resId){ImageView iv=getView(viewId);iv.setImageDrawable(mContext.getResources().getDrawable(resId));return this;}/*** 加载图片资源路径* @param viewId* @param imageLoader* @return*/public ViewHolder setImagePath(int viewId,HolderImageLoader imageLoader,int res){ImageView iv=getView(viewId);imageLoader.loadImage(iv,imageLoader.getPath(),res);return this;}public ViewHolder setImage(Context mContext, int viewId, String url, int res) {ImageView view = getView(viewId);GlideLoadImageUtils.loadRectangleImg(mContext, view, url,res);return this;}public ViewHolder setCircleImage(Context mContext, int viewId, String url, int res) {ImageView view = getView(viewId);GlideLoadImageUtils.loadCircleImg(mContext, view, url,res);return this;}public ViewHolder setTextColor(Context mContext, int viewId, int color) {TextView tv = (TextView)this.getView(viewId);tv.setTextColor(mContext.getResources().getColor(color));return this;}public ViewHolder setTextSize(Context mContext, int viewId, float res) {TextView tv = (TextView)this.getView(viewId);tv.setTextSize(Utils.dp2px(mContext,res));return this;}@SuppressLint("NewApi")public ViewHolder setBackground(Context mContext, int viewId, int bg) {TextView tv = (TextView)this.getView(viewId);tv.setBackground(mContext.getResources().getDrawable(bg));return this;}/*** 关于事件的*/public ViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {View view = getView(viewId);view.setOnClickListener(listener);return this;}public abstract static class HolderImageLoader{public String mPath;public Context mContext;public HolderImageLoader(Context mContext, String path){this.mPath=path;this.mContext = mContext;}/*** 需要去复写这个方法加载图片* @param iv* @param path*/public abstract void loadImage(ImageView iv, String path, int res);public String getPath(){return mPath;}}}

3、activity中使用

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

/*** 控制通知公告数据滚动* 手指滑动时 停止自动滚动* 手指抬起时,3秒后自动开始滚动*/private void initRlvNews() {scroHandler = new Handler();//定义handlerrunnable = () -> {  //runnable方法,处理延时后的操作newsAdapter.setItemCount(0);//0表示手指已经抬起来了rlvNews.start(); //开始滑动};rlvNews.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);if (null != newsAdapter) {if (newState == 1) {//newState的值:1 手指按下拖拽滚动,2自动滚动(一般指惯性滚动),0 禁止没有滚动rlvNews.stop();//停止自动滚动newsAdapter.setItemCount(newState);} else {scroHandler.removeCallbacks(runnable);//清除runnable重新开始//这里设置3秒是预估了手指滑动抬起再滑动的时间,提升体验scroHandler.postDelayed(runnable, 3000);}}}});}

4、布局文件:

  需要给固定高度

<com.anyi.credit.bank.view.SocllRecyclerViewandroid:id="@+id/rlvNews"android:layout_width="match_parent"android:layout_height="144dp"/>

5、数据绑定

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

        MyscrviewAdapter adpter=new MyscrviewAdapter(this,list)

        rlvNews.setAdapter(adpter)

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

        if(list.size()>4){

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

        }

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/625727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue Grid Layout ( 栅格布局 )

Vue Grid Layout -️ 适用 Vue.js 的栅格布局系统 (相关使用记录) 参考文章~朴&#xff1a;shu参考文章我说爱你啊中文文档官方文档 安装 npm install vue-grid-layout --save 或yarn add vue-grid-layout导入组件 import VueGridLayout from vue-grid-layout;注册组件 expor…

C语言从入门到实战——结构体与位段

结构体与位段 前言一、结构体类型的声明1.1 结构体1.1.1 结构的声明1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明1.3 结构的自引用 二、 结构体内存对齐2.1 对齐规则2.2 为什么存在内存对齐2.3 修改默认对齐数 三、结构体传参四、 结构体实现位段4.1 什么是位段4.2 位段…

基于springboot的流浪动物救助管理系统

&#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;一 、设计说明 1.1研究背景 随着…

MStart | MStart开发与学习

MStart | MStart开发与学习 1.学习 1.MStart |开机LOG显示异常排查及调整

windows平台高dpi介绍

flutter在windows平台如何自定义dpi设置 系统层级的支持(windows平台对高dpi的支持) 主要有两点&#xff1a; 设置系统的缩放比例 (系统及系统自带的app会根据这个设置来进行缩放&#xff1b;自己的app需要结合自己设置的dpi awareness来实现对应的dpi支持)设置进程的dpi aw…

Linux系统中负载较高问题排查思路与解决方法

Load 就是对计算机干活多少的度量&#xff0c;Load Average 就是一段时间&#xff08;1分钟、5分钟、15分钟&#xff09;内平均Load。 一、Load分析&#xff1a; 情况1&#xff1a;CPU高、Load高 通过top命令查找占用CPU最高的进程PID&#xff1b;通过top -Hp PID查找占用CPU…

BIOS知识枝桠——RAID 磁盘阵列

文章目录 前言一、RAID介绍二、RAID等级分类1.RAID02.RAID13.RAID24.RAID3和RAID45.RAID5和RAID66.RAID77.RAID10 BIOS下组建RAID 前言 假设存在多块磁盘&#xff0c;如果不组建阵列&#xff0c;磁盘与磁盘之间是没有任何关系的。磁盘A和B&#xff0c;放在A中的文件与B磁盘没有…

vue中使用component中的is渲染组件如何使用,:is 等价 v-if渲染组件。

动态组件顾名思义动态加载不同的组件&#xff0c;is属性用于加载不同组件&#xff0c;传参使用属性传递 1、使用v-for遍历component&#xff0c;组件都会执行 <componentv-for"(item, index) in TAB_PANE":key"index":is"item.componentName"…

Java多线程——并发和并行、实现方法

多线程 并发和并行 实现方法 代码演示 方式一 package com.qiong.thread1;public class MyThread extends Thread{Overridepublic void run() {for (int i 0; i < 20; i) {System.out.println(getName() "Hello World");}} }package com.qiong.thread1;public…

训练营四十四天 | ● 完全背包● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ

完全背包 先物品再背包和先背包再物品都行&#xff0c;背包正序遍历&#xff0c;可以重复选取 先物品再背包是组合&#xff0c;不讲究各个物品的不同顺序&#xff0c;因为先顺序遍历物品&#xff0c;所以物品只有一种排序&#xff0c;即组合 先背包再物品是排序&#xff0c;物…

运筹说 第65期 | 动态规划的基本概念和基本原理

20世纪50年代初&#xff0c;美国数学家R. Bellman 等人在解决多阶段决策优化问题时提出了一种高效的求解方法——动态规划&#xff08;Dynamic Programming&#xff09;&#xff0c;该方法基于多阶段决策优化问题的特点&#xff0c;把多阶段问题转换为一系列互相联系的单阶段问…

2024抖店选品方法,及侧重方向思路(全新版本),可收藏备用

我是王路飞。 做无货源抖店的商家&#xff0c;牢记【选品重于泰山】这句话。 要知道电商的本质就是产品&#xff0c;你所有的运营手段也都是围绕产品进行的&#xff0c;店铺内的流量也都是冲着产品来的。 产品不行&#xff0c;哪怕再多的流量、再高的曝光率&#xff0c;也带…

2024年全网最全春招时间线

2024年全网最全春招时间线 春招&#xff0c;许多同学可能会误以为这是春天才会进行。 你可能会想&#xff0c;期末刚考完试&#xff0c;先享受下寒假&#xff0c;再欢度春节&#xff0c;收些红包&#xff0c;甚至还能抽空去理个发型。等到春日明媚时&#xff0c;再参加春招活…

linux docker安装 rustdesk

这里写自定义目录标题 1&#xff1a;软件介绍&#xff1a;2&#xff1a;安装1. 服务器端2. 客户端 3&#xff1a;配置5&#xff1a;其他1:rustdesk 官方Docker Compose 1&#xff1a;软件介绍&#xff1a; 名称作用官网项目地址rustdesk实现多端互控https://rustdesk.com/inde…

将github项目导入gitee中

首先将原gitee项目中以下不必要的文件删除掉&#xff0c;并把github中的文件下载到gitee目录下&#xff1a; rm -rf * git clone [链接]cd 进入下载后的目录&#xff0c;将下载后的git相关文件删除&#xff1a; cd [git项目名] rm -rf .git回到gitee项目文件夹&#xff0c;将…

图书管理系统:从数据库设计到前端展示的实战经验分享

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Arduino| 串口通讯、入门示例

Arduino串口通讯 为什么要做串口通讯串口通讯原理串口通讯函数字符串常用函数串口通讯示例入门示例测试串口通讯复杂指令处理 为什么要做串口通讯 串口通讯&#xff1a;串口通信是用来在不同电子设备之间交换数据用的技术&#xff0c;其实就是要实现不同电子设备之间的“通讯对…

C# Cad2016二次开发选择文本信息导出(六)

//选文本信息导出 [CommandMethod("getdata")] public void getdata() {// 获取当前文档和数据库Document doc Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;Database db doc.Database;Editor ed doc.Editor;// 获取当前…

vulnhub靶场之DC-9

一.环境搭建 1.靶场描述 DC-9 is another purposely built vulnerable lab with the intent of gaining experience in the world of penetration testing. The ultimate goal of this challenge is to get root and to read the one and only flag. Linux skills and famili…

01-11NodeJS

NodeJSNpmBootstrap NodeJS 概念&#xff1a;NodeJS是JavaScript的运⾏环境: node xxx&#xff0c;主要在Windows、Linux、Unix、MacOSX等不同平台上运行 一、特点&#xff1a; 单线程异步IO跨平台事件驱动 能让JS脱离浏览器执行可以开发后端程序 二、测试&#xff1a; 安…