赞
踩
概要
做一个自动滑动的列表,用于展示聊天记录或者通知栏信息等,还是使用主流的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);
- }
-
- @Override
- public 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);
- }
-
- @Override
- public 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
- @Override
- public 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;
- }
-
- @Override
- public 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() {
- @Override
- public void onClick(View v) {
- if (null != mItemClickListener) {
- mItemClickListener.onItemClick(mies.get(position % mies.size()), position);
- }
- }
- });
- }
-
- @Override
- public 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();//定义handler
- runnable = () -> { //runnable方法,处理延时后的操作
- newsAdapter.setItemCount(0);//0表示手指已经抬起来了
- rlvNews.start(); //开始滑动
- };
- rlvNews.addOnScrollListener(new RecyclerView.OnScrollListener() {
- @Override
- public 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.SocllRecyclerView
- android: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(); //开始滑动
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。