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

本文主要是介绍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(); //开始滑动

        }

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

这篇关于Android 自动滚动的RecyclerView,手动滑动和自动滑动无缝衔接,手动滑动时数据不重复的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/610904

相关文章

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

MySQL中的DELETE删除数据及注意事项

《MySQL中的DELETE删除数据及注意事项》MySQL的DELETE语句是数据库操作中不可或缺的一部分,通过合理使用索引、批量删除、避免全表删除、使用TRUNCATE、使用ORDERBY和LIMI... 目录1. 基本语法单表删除2. 高级用法使用子查询删除删除多表3. 性能优化策略使用索引批量删除避免

2025最新版Android Studio安装及组件配置教程(SDK、JDK、Gradle)

《2025最新版AndroidStudio安装及组件配置教程(SDK、JDK、Gradle)》:本文主要介绍2025最新版AndroidStudio安装及组件配置(SDK、JDK、Gradle... 目录原生 android 简介Android Studio必备组件一、Android Studio安装二、A

MySQL 数据库进阶之SQL 数据操作与子查询操作大全

《MySQL数据库进阶之SQL数据操作与子查询操作大全》本文详细介绍了SQL中的子查询、数据添加(INSERT)、数据修改(UPDATE)和数据删除(DELETE、TRUNCATE、DROP)操作... 目录一、子查询:嵌套在查询中的查询1.1 子查询的基本语法1.2 子查询的实战示例二、数据添加:INSE

Linux服务器数据盘移除并重新挂载的全过程

《Linux服务器数据盘移除并重新挂载的全过程》:本文主要介绍在Linux服务器上移除并重新挂载数据盘的整个过程,分为三大步:卸载文件系统、分离磁盘和重新挂载,每一步都有详细的步骤和注意事项,确保... 目录引言第一步:卸载文件系统第二步:分离磁盘第三步:重新挂载引言在 linux 服务器上移除并重新挂p

使用MyBatis TypeHandler实现数据加密与解密的具体方案

《使用MyBatisTypeHandler实现数据加密与解密的具体方案》在我们日常的开发工作中,经常会遇到一些敏感数据需要存储,比如用户的手机号、身份证号、银行卡号等,为了保障数据安全,我们通常会对... 目录1. 核心概念:什么是 TypeHandler?2. 实战场景3. 代码实现步骤步骤 1:定义 E

使用C#导出Excel数据并保存多种格式的完整示例

《使用C#导出Excel数据并保存多种格式的完整示例》在现代企业信息化管理中,Excel已经成为最常用的数据存储和分析工具,从员工信息表、销售数据报表到财务分析表,几乎所有部门都离不开Excel,本文... 目录引言1. 安装 Spire.XLS2. 创建工作簿和填充数据3. 保存为不同格式4. 效果展示5

Python多任务爬虫实现爬取图片和GDP数据

《Python多任务爬虫实现爬取图片和GDP数据》本文主要介绍了基于FastAPI开发Web站点的方法,包括搭建Web服务器、处理图片资源、实现多任务爬虫和数据可视化,同时,还简要介绍了Python爬... 目录一. 基于FastAPI之Web站点开发1. 基于FastAPI搭建Web服务器2. Web服务