【Android】viewpager和recyclerview联动知识梳理

最近做一个需求,界面上方是一个可滑动切换的viewpager列表,下方是一个用recyclerview做的菜单,recyclerview的item对应viewpager的一页,要求在滑动上面或者下面的时候另一个都要跟着滑动,就好像你执行一次滑动却产生了两个事件序列。

我的思路是分别对viewpager和recyclerview的滑动进行监听,比如viewpager滑动了就计算出他本次滑动到了哪个position,相对于这个position的offset是多少,然后把position和offset传给recyclerview使其滑动到指定的位置。在这个过程中梳理了一下相关的知识点:

1.ViewPager:

FragmentStatePagerAdapter和FragmentPagerAdapter的区别主要在于destroyItem的实现,刚开始的时候我们会给viewpager设置离屏的缓存数量,对于超出缓存范围的fragment,前者会直接从FragmentManager中remove,也就是销毁;而后者只是调用fragment的detach方法销毁视图(这时调用getView返回的是null)。对于本需求这种多页面的来说明显用FragmentPagerAdapter会占用过多内存。

滑动:滑动监听使用addOnPageChangeListener的onPageScrolled回调方法,参数包括页面position和相对这个页面的offset,很方便。如果我们想要翻过一页的话,需要滑动多少距离呢,如果调用了setPageMargin的话,那么就是一页的width+pageMargin。

页面切换效果:如果通过setPageTransformer设置了切换效果,那么在调用scrollTo手动控制viewpager滑动的时候还要处理这个效果,他不会自动处理。处理方式就是调用transformer.transformPage,需要对切换前后两个页面都调用此方法设置这两个页面的切换中状态。

Viewpager和RecyclerView都没有重写getChildAt,这个方法获取到的View并不可靠,可能只能拿到当前可见的child。ViewPager可以在fragment的onCreateView里给view.setTag。然后通过findViewWithTag获取就可以了,前提是对应的fragment没有销毁视图,这个view还存在。

2.RecyclerView:

滑动:滑动的阶段包括开始滑动、滑动中、手机松开后的惯性滑动(当时的滑动速度够才会触发)、滑动结束。这些状态的变化可以通过addOnScrollListener的onScrollStateChanged来监听。setOnFlingListener返回true可以去除原有的惯性滑动效果,不过滑动状态会乱套,一次滑动后不会触发滑动结束状态:SCROLL_STATE_IDLE。recyclerview的onIntereptTouchEvent判断是否拦截事件,其中一个判断条件就是当前的滑动状态,如果不是SCROLL_STATE_IDLE就会拦截处理,那么item也就收不到事件,不能响应点击等操作了。

总滑动距离没有一个api来获取,我的方法是在addOnScrollListener的onScrolled里累加滑动距离(惯性滑动fling也在里面),记录总滑动距离。computeHorizontalScrollOffset是根据当前position和offset算出来的,只适用于所有item的宽度或高度相同的情况。

3.其他:

scrollBy实际上调用的还是scrollTo

你可能感兴趣的:(【Android】viewpager和recyclerview联动知识梳理)