iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android如何使用RecyclerView打造首页轮播图
  • 658
分享到

Android如何使用RecyclerView打造首页轮播图

轮播图首页recyclerview轮播Android 2022-06-06 04:06:45 658人浏览 独家记忆
摘要

先看看效果图: 停在中间自动翻页 序言:最近接到一个任务,做一个类似上面自动翻页的功能。可以看到,这一屏中有三张图片显示出来了,有两张没有显示完全,看到设计图的时候第一反应

先看看效果图:

停在中间自动翻页

停在中间自动翻页

序言:最近接到一个任务,做一个类似上面自动翻页的功能。可以看到,这一屏中有三张图片显示出来了,有两张没有显示完全,看到设计图的时候第一反应是可以用viewpager来实现,但是任务却跟你开了一个天大的玩笑,要求是以最左边的图片为基准,也就是说,左边的图片也得显示完全,就像下图所示,后来仔细想想viewpager好像没有这样的功能,也有可能是我不知道,我也没有找到这样的文章或者信息,希望知道的简友私戳交流一下,感激不尽,好了,言归正传

停在中间自动翻页

停在左边

在开始之前呢,首先介绍一个Google最新(其实在24.2.0版本的时候就已经发布了)发布的一个东西SnapHelper,这玩意儿是对RecyclerView功能的一个拓展,有兴趣的同学可以去看看它的源码,SnapHelper的实现原理是监听RecyclerView.OnFlingListener中的onFling接口,可以使RecyclerView实现类似ViewPager的功能,无论怎么滑动最终停留在某页正中间,那它和ViewPager的区别是什么呢?就是ViewPager不能一次连续滑动多张图片,而且不能定制(停在左边,还是停在右边)。下面我们一起来看看吧!

首先导入所需要的包,最低版本是v7-24.2.0,低了就没有这个类了:

compile 'com.Android.support:appcompat-v7:24.2.0'
compile 'com.android.support:recyclerview-v7:24.2.0'

这里系统自带有一个类LinearSnapHelper,LinearSnapHelper继承自SnapHelper,这个默认是让视图停在中间的,你只需要将RecyclerView和LinearSnapHelper绑定在一起就行了:

LinearSnapHelper mLinearSnapHelper = new LinearSnapHelper();
mLinearSnapHelper.attachToRecyclerView(mRecyclerview);

效果如下:

停在中间自动翻页

当然了,SnapHelper的功能绝不仅仅在此,你还可以定制化,让他停在左边,或者右边,而你不需要重新继承SnapHelper,直接继承LinearSnapHelper就可以了,这里面有很多写好的方法,然后你再重写里面的两个方法:
* (1)、calculateDistanceToFinalSnap:当拖拽或滑动结束时会回调该方法,返回一个out = int[2],out[0]x轴,out[1] y轴 ,这个值就是需要修正的你需要的位置的偏移量。 *
* (2)、findSnapView:这个方法用来获取特定的视图,当返回null时,表示没有获取到任何视图 。*

完整的代码:


public class LeftSnapHelper extends LinearSnapHelper {
 private OrientationHelper mHorizontalHelper;
 
 @Override
 public int[] calculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView) {
 //注:由于是横向滚动,在这里我们只考虑横轴的值
 int[] out = new int[2];
 if (layoutManager.canScrollHorizontally()) {
  out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
 } else {
  out[0] = 0;
 }
 return out;
 }
 
 private int distanceToStart(View targetView, OrientationHelper helper) {
 return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
 }
 @Override
 public View findSnapView(RecyclerView.LayoutManager layoutManager) {
 return findStartView(layoutManager, getHorizontalHelper(layoutManager));
 }
 
 private View findStartView(RecyclerView.LayoutManager layoutManager,
    OrientationHelper helper) {
 if (layoutManager instanceof LinearLayoutManager) {
  int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
  int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
  if (firstChild == RecyclerView.NO_POSITION) {
  return null;
  }
  //这是为了解决当翻到最后一页的时候,最后一个Item不能完整显示的问题
  if (lastChild == layoutManager.getItemCount() - 1) {
  return layoutManager.findViewByPosition(lastChild);
  }
  View child = layoutManager.findViewByPosition(firstChild);
  //得到此时需要左对齐显示的条目
  if (helper.getDecoratedEnd(child) >= helper.getDecoratedMeasurement(child) / 2
   && helper.getDecoratedEnd(child) > 0) {
  return child;
  } else {
  return layoutManager.findViewByPosition(firstChild + 1);
  }
 }
 return super.findSnapView(layoutManager);
 }
 
 private OrientationHelper getHorizontalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
 if (mHorizontalHelper == null) {
  mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
 }
 return mHorizontalHelper;
 }
}

当然了,你也可以让它停在右边:只需要在上面的基础上修改findSnapView方法即可:


public class RightSnapHelper extends LinearSnapHelper {
 private OrientationHelper mHorizontalHelper;
 
 @Override
 public int[] calculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView) {
 //注:由于是横向滚动,在这里我们只考虑横轴的值
 int[] out = new int[2];
 if (layoutManager.canScrollHorizontally()) {
  out[0] = distanceToEnd(targetView, getHorizontalHelper(layoutManager));
 } else {
  out[0] = 0;
 }
 return out;
 }
 
 private int distanceToEnd(View targetView, OrientationHelper helper) {
 return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding();
 }
 @Override
 public View findSnapView(RecyclerView.LayoutManager layoutManager) {
 return findEndView(layoutManager, getHorizontalHelper(layoutManager));
 }
 
 private View findEndView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
 if (layoutManager instanceof LinearLayoutManager) {
  int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
  if (lastChild == RecyclerView.NO_POSITION) {
  return null;
  }
  View child = layoutManager.findViewByPosition(lastChild);
  //得到此时需要右对齐显示的条目
  if (helper.getDecoratedStart(child) >= helper.getDecoratedMeasurement(child) / 2
   && helper.getDecoratedStart(child) > 0) {
  return child;
  } else {
  return layoutManager.findViewByPosition(lastChild - 1);
  }
 }
 return super.findSnapView(layoutManager);
 }
 
 private OrientationHelper getHorizontalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
 if (mHorizontalHelper == null) {
  mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
 }
 return mHorizontalHelper;
 }
}

效果:

停在中间自动翻页

停在右边

那如何让它能无限的滑动呢?

这个当然是要在Adapter里面“做手脚”了,让获取Item总数的方法返回Integer.MAX_VALUE就可以了:


@Override
public int getItemCount() {
 return Integer.MAX_VALUE;
}

然后在onBindViewHolder中获取list中的值时相应的取余就好了:


@Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
 Glide.with(mContext).load(mList.get(position % mList.size())
  .getImageUrl()).placeholder(R.mipmap.ic_launcher)
  .into(holder.ivImage);
 holder.tvName.setText(mList.get(position % mList.size()).getName());
}

好了,做到这里就完成了80%了,接下来我们要让它能够自动滚动,如何能自动滚动呢?这里可以参考一下ViewPager中自动滚动的效果,这里LZ使用的是Timer来实现,Timer有一个每隔多长时间执行一次的功能,在这里正好:


private int cnt = 2; //表示当前最右边显示的item的position
private boolean isSlidingByHand = false; //表示是否是手在滑动
private boolean isSlidingAuto = true; //表示是否自动滑动
timer.schedule(new TimerTask() {
 @Override
 public void run() {
  if (isSlidingAuto) {
  myHandler.sendEmptyMessage(CHANGE_ITEM);
  }
 }
 }, 1000, 3000);

考虑到这里有两种滑动,一种是用户手动的滑动,另一种是我们的Timer来出发滑动,我们还得对RecyclerView设置监听,来简单判断一下是用户触发的还是Timer触发的:


alRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
 @Override
 public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager();
  int firstVisibleItemPosition = manager.findFirstVisibleItemPosition();
  switch (newState) {
  case SCROLL_STATE_IDLE: //(静止没有滚动)
   if (isSlidingByHand) {
   Message msg = myHandler.obtainMessage();
   msg.arg1 = firstVisibleItemPosition;
   msg.what = CHANGE_ITEM;
   myHandler.sendMessage(msg);
   }
   break;
  case SCROLL_STATE_DRAGGING: //(正在被外部拖拽,一般为用户正在用手指滚动)
   isSlidingByHand = true;
   isSlidingAuto = false;
   break;
  case SCROLL_STATE_SETTLING: //(自动滚动)
   if (isSlidingByHand) {
   isSlidingAuto = false;
   } else {
   isSlidingAuto = true;
   }
   break;
  }
 }
 });

最后的处理结果当然是交给Handler来了:


private static class MyHandler extends Handler {
 //采用弱引用的方式,防止内存泄漏
 WeakReference<CenterActivity> weakReference;
 public MyHandler(CenterActivity Mactivity) {
 this.weakReference = new WeakReference<>(mActivity);
 }
 @Override
 public void handleMessage(Message msg) {
 final CenterActivity mActivity = weakReference.get();
 Log.d(TAG, "handleMessage: " + "handler is running");
 if (mActivity.isSlidingByHand) {
  mActivity.cnt = msg.arg1;
  mActivity.isSlidingByHand = false;
  mActivity.isSlidingAuto = true;
  mActivity.cnt+=2;
  //让RecyclerView平滑的滚动
  mActivity.alRecyclerview.smoothScrollToPosition(++mActivity.cnt);
 } else {
  mActivity.alRecyclerview.smoothScrollToPosition(++mActivity.cnt);
 }
 }
}

这样差不多就好了,但是还有一个问题不知道各位有没有关注到,滚动的时候并没有那么平滑,找了好久不知道是什么原因,希望知道的朋友底下评论告知一声。

参考文章:
OrientationHelper api
Android24.2.0支持库中的SnapHelper学习和使用

感谢以上资料的帮助。

源码我已上传至GitHub,想了解的朋友可以自行下载,当然,如果有更好的想法,也可以一起交流。

您可能感兴趣的文章:Android ViewPager实现轮播图效果Android自定义控件实现简单的轮播图控件Android自定义控件实现优雅的广告轮播图Android实现ViewPage轮播图效果Android实现炫酷轮播图效果Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件简单实现android轮播图Android开发在轮播图片上加入点击事件的方法Android实现轮播图无限循环效果Flutter实现轮播图效果


--结束END--

本文标题: Android如何使用RecyclerView打造首页轮播图

本文链接: https://www.lsjlt.com/news/22429.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用jQuery实现优酷首页轮播图
    这篇文章给大家分享的是有关如何使用jQuery实现优酷首页轮播图的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。思路思路其实非常简单,就是当点击图片下面的圆点或者图片两边的箭头时,...
    99+
    2024-04-02
  • angularjs如何实现首页轮播图效果
    这篇文章给大家分享的是有关angularjs如何实现首页轮播图效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体内容如下<!DOCTYPE html> ...
    99+
    2024-04-02
  • JavaScript如何实现首页图片轮播图效果
    这篇文章主要介绍“JavaScript如何实现首页图片轮播图效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript如何实现首页图片轮播图效果”文章能帮助大家解决问题。一、轮番图效果展...
    99+
    2023-07-02
  • Android使用Recyclerview实现图片轮播效果的方法
    这篇文章将为大家详细讲解有关Android使用Recyclerview实现图片轮播效果的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。效果图:思路:准备m张图片使用Recyclerview实现,返回无...
    99+
    2023-05-30
    android recyclerview 滚动效果
  • android轮播图如何实现
    在Android中实现轮播图可以使用ViewPager和PagerAdapter来实现。下面是一个简单的实现步骤:1. 在XML布局...
    99+
    2023-08-19
    android
  • Android使用RollViewPager实现轮播图
    记录Android中轮播图的学习与使用,供大家参考,具体内容如下 1、build.gradle(:app)文件里面加依赖 implementation 'com.jude:ro...
    99+
    2024-04-02
  • android如何实现banner轮播图无限轮播效果
    小编给大家分享一下android如何实现banner轮播图无限轮播效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体内容如下效果展示第一步(权限配置)<uses-permission android:n...
    99+
    2023-05-30
    android banner
  • 如何使用JS做网页大图轮播特效
    小编给大家分享一下如何使用JS做网页大图轮播特效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!代码如下:<style>...
    99+
    2024-04-02
  • js如何实现图片首尾平滑轮播
    这篇文章给大家分享的是有关js如何实现图片首尾平滑轮播的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先给出HTML代码,要注意轮播图片表(#list)末尾加上第一个图片1.jp...
    99+
    2024-04-02
  • 如何使用JavaScript实现轮播图
    这篇文章主要介绍了如何使用JavaScript实现轮播图,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 wxml(使用官方的等等组件来展示...
    99+
    2024-04-02
  • Android如何使用ViewFlipper实现图片上下自动轮播
    这篇文章主要介绍了Android如何使用ViewFlipper实现图片上下自动轮播,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体如下:先看效果:1.xml代码: ...
    99+
    2023-06-15
  • 如何使用vue实现轮播图片
    这篇“如何使用vue实现轮播图片”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何使用vue实现轮播图片”文章吧。效果图案例...
    99+
    2023-07-02
  • Android中RecyclerView如何使用
    本篇文章给大家分享的是有关Android中RecyclerView如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。RecyclerView 是在Android suppo...
    99+
    2023-05-30
    android recyclerview
  • 如何使用python画城市轮播地图
    这篇文章将为大家详细讲解有关如何使用python画城市轮播地图,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。这里是以其中5个省份的城市为例进行演示画图前准备在画图之前先导入相关的库from py...
    99+
    2023-06-15
  • 小程序如何设置页面的轮播图
    小程序制作banner轮播图进入微信开发者工具,打开小程序文件目录;在文件目录中,依次查找:test/test.wxml文件;打开test.wxml文件,使用swiper标签来包裹轮播图片,代码如下:<swiper indi...
    99+
    2024-04-02
  • android ViewPager如何实现一个无限轮播图
    这篇文章主要介绍android ViewPager如何实现一个无限轮播图,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!首先我们需要建一个包,然后新建一个java类,名字随便起这个类我们需要随便继承自一个vi...
    99+
    2023-06-29
  • ViewPager如何实现轮播图Banner/引导页Guide
    小编给大家分享一下ViewPager如何实现轮播图Banner/引导页Guide,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Banner效果: Github链接...
    99+
    2023-05-30
    viewpager banner guide
  • Android Banner本地和网络轮播图使用介绍
    目录加载本地图片第一步:先在build.gradle中加入banner和glide的依赖第二步:xml布局第三步:MainActivity加载网络图片下载网络图片的时候要记得添加网络...
    99+
    2024-04-02
  • css如何制作途牛旅游网首页轮番图
    这篇文章主要介绍css如何制作途牛旅游网首页轮番图,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!<!doctype html><html lang="en...
    99+
    2024-04-02
  • 如何使用JQuery实现图片轮播效果
    这篇文章主要介绍了如何使用JQuery实现图片轮播效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。【效果如图】【原理简述】这里大概说一下整...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作