美文网首页AndroidAndroid技术知识程序员
使用 RecyclerView 实现轮播图

使用 RecyclerView 实现轮播图

作者: 四月一号 | 来源:发表于2016-10-23 17:21 被阅读6894次

之前总结了实现轮播图的各种方式.不过总的来说,基本都是通过viewpager来实现.并且效果也不能称为 完美 . 在IOS中,实现轮播图的方式更为丰富,什么两图轮播,三图轮播... 所以偶尔我也思考是否还有其它方式可以实现.

Google官方提供的可滑动控件无非就是ScrollView,ListView,RecyclerView等等. 其中RecyclerView就是专门处理视图回收的,那么是否可以使用RecyclerView来实现呢?

使用RecyclerView来轮播,首先需要解决两个问题

  • 一次只能滑动一页
  • 不能滑一半,每次停止的时候,都要让当前页居中显示

本来要实现这个功能是挺麻烦的,幸好在 RecyclerView-24.2.0(大概是)开始,新增了一个类可以帮助我们完成90%,那就是 LinearSnapHelper.

LinearSnapHelper的使用很简单:

new LinearSnapHelper().attachToRecyclerView(recyclerView);

只需要上面这行代码,RecyclerView就能实现类似ViewPager的功能,在滑动停止的时候,让某页居中显示.唯一的不同,就是RecyclerView一次可以滑动很多页.
其实这样就已经完全足够了,当然如果你一定想每次都只能滑动一页,那么就需要重写一下 LinearSnapHelper 的 findTargetSnapPosition 方法. findTargetSnapPosition 就是 LinearSnapHelper 通过当前滑动速度,计算最终定位position的方法.

private class PagerSnapHelper extends LinearSnapHelper {    
     @Override    
     public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {        
        int targetPos = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);        
        final View currentView = findSnapView(layoutManager);        
        if(targetPos != RecyclerView.NO_POSITION && currentView != null){            
           int currentPostion = layoutManager.getPosition(currentView);            
           int first = ((LinearLayoutManager)layoutManager).findFirstVisibleItemPosition();            
           int last = ((LinearLayoutManager)layoutManager).findLastVisibleItemPosition();           
           currentPostion = targetPos < currentPostion ? last : (targetPos > currentPostion ? first : currentPostion);            
           targetPos = targetPos < currentPostion ? currentPostion - 1 : (targetPos > currentPostion ? currentPostion + 1 : currentPostion);        
         }        
        return targetPos;    
     }
}

在上面的代码中,稍微耍了点小心思,就是通过原来计算的结果,如果是往前滑动,那么就重新赋值为当前位置 - 1 ; 如果是往后滑动,那就则重新赋值为当前位置 + 1. 到这里,RecyclerView的效果就完全和ViewPager一致了.

因为RecyclerView内部完美的处理了视图的回收,所以实现轮播图的思路也就很明确了:

  1. 给适配器设置为无限大,

  2. 然后将初始位置通过 scrollToPosition() 定位在中间某个地方,完全不用担心像使用ViewPager一样的ANR问题,

  3. 通过定时器,每隔一定事件调用

    // 向后翻动一页 
    recyclerView.smoothScrollToPosition(++currentIndex);
    
  4. 刷新的时候,通过 notifyDataSetChanged()更新数据,不用每次再重新设置适配器了.

其它的思路,就和 全面总结轮播图 中的最终方式一样了,这里不再重复.
效果也和之前非常类似:

S61023-153210.jpg

代码在这里

相关文章

网友评论

  • 吉凶以情迁:问题是gridlayout居中错误,并不是我想要的居中。怎么办?
  • 云佾风徽:请问我按照你的思路实现以后,setDatas里
    recyclerView.scrollToPosition(currentIndex);
    会从0开始一直快速滑动到中间位置,你有遇到过吗
  • Nebula995:这个不错,回去试试

本文标题:使用 RecyclerView 实现轮播图

本文链接:https://www.haomeiwen.com/subject/hsrkuttx.html