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

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

poj2406(连续重复子串)

题意:判断串s是不是str^n,求str的最大长度。 解题思路:kmp可解,后缀数组的倍增算法超时。next[i]表示在第i位匹配失败后,自动跳转到next[i],所以1到next[n]这个串 等于 n-next[n]+1到n这个串。 代码如下; #include<iostream>#include<algorithm>#include<stdio.h>#include<math.

poj3261(可重复k次的最长子串)

题意:可重复k次的最长子串 解题思路:求所有区间[x,x+k-1]中的最小值的最大值。求sa时间复杂度Nlog(N),求最值时间复杂度N*N,但实际复杂度很低。题目数据也比较水,不然估计过不了。 代码入下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo