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

作者:24K纯帅豆 时间:2022-06-08 13:15:39 

本文实例为大家分享了Android使用RecyclerView打造首页轮播图的具体代码,供大家参考,具体内容如下

先看看效果图:

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

停在中间自动翻页

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

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

停在左边

在开始之前呢,首先介绍一个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);

效果如下:

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

当然了,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;

/**
* 当拖拽或滑动结束时会回调该方法,该方法返回的是一个长度为2的数组,out[0]表示横轴,x[1]表示纵轴,这两个值就是你需要修正的位置的偏移量
*
* @param layoutManager
* @param targetView
* @return
*/
@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;
}

/**
* 这个方法是计算偏移量
*
* @param targetView
* @param helper
* @return
*/
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));
}

/**
* 找到第一个显示的view
* @param layoutManager
* @param helper
* @return
*/
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);
}

/**
* 获取视图的方向
*
* @param layoutManager
* @return
*/
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;

/**
* 当拖拽或滑动结束时会回调该方法,该方法返回的是一个长度为2的数组,out[0]表示横轴,x[1]表示纵轴,这两个值就是你需要修正的位置的偏移量
*
* @param layoutManager
* @param targetView
* @return
*/
@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;
}

/**
* 这个方法是计算偏移量
*
* @param targetView
* @param helper
* @return
*/
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));
}

/**
* 找到第一个显示的view
*
* @param layoutManager
* @param helper
* @return
*/
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);
}

/**
* 获取视图的方向
*
* @param layoutManager
* @return
*/
private OrientationHelper getHorizontalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
if (mHorizontalHelper == null) {
 mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
}
return mHorizontalHelper;
}
}

效果:

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

停在右边

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

这个当然是要在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());
}
标签:RecyclerView,轮播图
0
投稿

猜你喜欢

  • Spring存储与读取Bean对象方法

    2021-11-12 03:35:27
  • mybatis-plus排除非表中字段的操作

    2022-04-22 03:48:41
  • Java实现LeetCode(1.两数之和)

    2021-06-03 02:11:19
  • c#多线程之线程基础

    2022-10-06 20:34:44
  • maven打包如何指定jdk的版本

    2022-12-21 20:59:20
  • Winform控件优化Paint事件实现圆角组件及提取绘制圆角的方法

    2022-04-04 15:41:13
  • Java中关于MouseWheelListener的鼠标滚轮事件详解

    2023-10-19 02:02:54
  • java批量修改文件后缀名方法总结

    2022-03-15 15:46:04
  • java关键字final使用方法详解

    2023-11-28 22:38:04
  • Java 使用 HttpClient 发送 GET请求和 POST请求

    2023-07-23 07:56:13
  • 妙解Java中的回调机制(CallBack)

    2022-07-15 15:25:31
  • Java图形用户界面设计(Swing)的介绍

    2022-08-23 03:29:37
  • 浅谈Spring Boot 开发REST接口最佳实践

    2021-10-08 12:24:35
  • Spring JPA联表查询之注解属性详解

    2021-11-04 14:19:04
  • Mybatis基于xml配置实现单表的增删改查功能

    2021-09-29 11:21:48
  • mybatis-plus乐观锁实现方式详解

    2022-09-27 16:12:27
  • Java之Spring注解开发案例详解

    2022-05-23 05:33:02
  • Android布局之帧布局FrameLayout详解

    2023-08-07 04:45:29
  • 解析JAVA深度克隆与浅度克隆的区别详解

    2023-11-02 10:57:28
  • SpringBoot整合XxlJob分布式任务调度平台

    2022-07-09 09:47:37
  • asp之家 软件编程 m.aspxhome.com