Android中使用RecyclerView + SnapHelper实现类似ViewPager效果

本文详细介绍了SnapHelper的功能及其在RecyclerView中的应用。SnapHelper是Google提供的一个组件,能够帮助开发者轻松实现列表项的对齐效果,例如居中显示或限制每次滑动一页等。文章还提供了LinearSnapHelper和PagerSnapHelper的具体使用示例。

    Google 在 Android 24.2.0 的support 包中添加了SnapHelper,SnapHelper是对RecyclerView的拓展,结合RecyclerView使用,能很方便的做出一些炫酷的效果。SnapHelper到底有什么功能呢?SnapHelper旨在支持RecyclerView的对齐方式,也就是通过计算对齐RecyclerView中TargetView 的指定点或者容器中的任何像素点。,可能有点不好理解,看了后文的效果和原理分析就好理解了。看一下文档介绍:

 

SnapHealper 介绍.png

 

SnapHelper继承自RecyclerView.OnFlingListener,并实现了它的抽象方法onFling, 支持SnapHelper的RecyclerView.LayoutManager必须实现RecyclerView.SmoothScroller.ScrollVectorProvider接口,或者你自己实现onFling(int,int)方法手动处理。SnapHeper 有以下几个重要方法:

  • attachToRecyclerView: 将SnapHelper attach 到指定的RecyclerView 上。

  • calculateDistanceToFinalSnap: 复写这个方法计算对齐到TargetView或容器指定点的距离,这是一个抽象方法,由子类自己实现,返回的是一个长度为2的int 数组out,out[0]是x方向对齐要移动的距离,out[1]是y方向对齐要移动的距离。

  • calculateScrollDistance: 根据每个方向给定的速度估算滑动的距离,用于Fling 操作。

  • findSnapView:提供一个指定的目标View 来对齐,抽象方法,需要子类实现

  • findTargetSnapPosition:提供一个用于对齐的Adapter 目标position,抽象方法,需要子类自己实现。

  • onFling:根据给定的x和 y 轴上的速度处理Fling。

LinearSnapHelper & PagerSnapHelper

上面讲了SnapHelper的几个重要的方法和作用,SnapHelper是一个抽象类,要使用SnapHelper,需要实现它的几个方法。而 Google 内置了两个默认实现类,LinearSnapHelperPagerSnapHelper ,LinearSnapHelper可以使RecyclerView 的当前Item 居中显示(横向和竖向都支持),PagerSnapHelper看名字可能就能猜到,使RecyclerView 像ViewPager一样的效果,每次只能滑动一页(LinearSnapHelper支持快速滑动), PagerSnapHelper也是Item居中对齐。接下来看一下使用方法和效果。

(1) LinearSnapHelper
LinearSnapHelper 使当前Item居中显示,常用场景是横向的RecyclerView, 类似ViewPager效果,但是又可以快速滑动(滑动多页)。代码如下:


 LinearLayoutManager manager = new LinearLayoutManager(getContext());
 manager.setOrientation(LinearLayoutManager.VERTICAL);
 mRecyclerView.setLayoutManager(manager);
// 将SnapHelper attach 到RecyclrView
 LinearSnapHelper snapHelper = new LinearSnapHelper();
 snapHelper.attachToRecyclerView(mRecyclerView);

代码很简单,new 一个SnapHelper对象,然后 Attach到RecyclerView 即可。

    上面的效果为LayoutManager的方向为VERTICAL,那么接下来看一下横向效果,很简单,和上面的区别只是更改一下LayoutManager的方向,代码如下:


 LinearLayoutManager manager = new LinearLayoutManager(getContext());
 manager.setOrientation(LinearLayoutManager.HORIZONTAL);
 mRecyclerView.setLayoutManager(manager);
// 将SnapHelper attach 到RecyclrView
 LinearSnapHelper snapHelper = new LinearSnapHelper();
 snapHelper.attachToRecyclerView(mRecyclerView);

    简单几行代码就可以用RecyclerView 实现一个类似ViewPager的效果,并且效果更赞。可以快速滑动多页,当前页剧中显示,并且显示前一页和后一页的部分。如果使用ViewPager来做还是有点麻烦的。除了上面的效果外,如果你想要和ViewPager 一样,限制一次只让它滑动一页,那么你就可以使用PagerSnapHelper了。

(2) PagerSnapHelper (在Android 25.1.0 support 包加入的)
PagerSnapHelper的展示效果和LineSnapHelper是一样的,只是PagerSnapHelper 限制一次只能滑动一页,不能快速滑动。代码如下:

PagerSnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(mRecyclerView);

    此外,在Github上发现一个实现了好几种Snap 效果的库,比如,start对齐、end对齐,top 对齐等等。有兴趣的可以去弄来玩一下,地址:[Snap 效果库]。(https://github.com/rubensousa/RecyclerViewSnap)。

 

PS:有些同学发现自己item不能全屏,也就是match parent没有效果。问题在于在Adapter的onCreateViewHolder创建子view的时候要把parent传进去; 

正确写法

LayoutInflater.from(context).inflate(R.layout.item_view,parent,false);

错误写法

LayoutInflater.from(context).inflate(R.layout.item_view,null);

转载于:https://my.oschina.net/zzxzzg/blog/1787619

介绍:一个基于RecyclerView实现ViewPager,支持类似于gallary的fling操作。点击上面"下载源码" 按钮,可以下载完整的demo。其中recyclerviewandroid-support中的依赖项目,RecyclerViewPager是主项目。运行效果使用说明:继承自 RecyclerView.自定义 fling factor.自定义 paging trigger.支持 水平个垂直方向.支持 FragmentViewPager (api 12 )gradlecompile('com.lsjwzh:recyclerviewpager:1.0.2')xml:java:final RecyclerViewPager mRecyclerView = (RecyclerViewPager) this.findViewById(R.id.recyclerViewPager); LinearLayoutManager layout = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL,false);//LinearLayoutManager.HORIZONTAL 设置水平滚动 mRecyclerView.setLayoutManager(layout); //set adapter mRecyclerView.setAdapter(new MyRecyclerAdapter());static class MyRecyclerAdapter extends RecyclerView.Adapter { private List items = new ArrayList(); public MyRecyclerAdapter(){ //创建4个页面 for(int i = 1; i<5; i ){ items.add("页面" i); } } public static class ViewHolder extends RecyclerView.ViewHolder{ public ViewHolder(View itemView) { super(itemView); } } @Override public int getItemCount() { // TODO Auto-generated method stub return items.size(); } @Override public void onBindViewHolder(ViewHolder holder, int position) { String item = items.get(position); TextView msgTv = (TextView)holder.itemView.findViewById(R.id.msg); msgTv.setText(item); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if(inflate == null) inflate = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = (LinearLayout)(inflate.inflate(R.layout.item, null)); return new 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值