RecyclerView滚动到指定位置并置顶

RecyclerView本身提供了几个定位的方法,除了手动滑动的scrollTo,smootScrollTo和scrollBy,smoothScrollBy方法之外,有一个直接滑动到指定位置item的scrollToPosition方法和另一个在此基础上平滑滚动的smoothScrollToPosition方法。但是经实验,该方法只能保证指定位置的item滑动到屏幕可见,如果指定的item本来就已在屏幕可见范围,则不会滑动,并且屏幕外的item滑到可见范围后,还需手动置顶。
常见处理方式
看了网上大多数相关的博客,一般的处理都是将item区分为 在可见范围以上/在可见范围内/在可见范围以下 三种情况,分别进行处理。
1、item在第一个可见item之前,直接用smoothScrollToPosition,则当该item移动到可见范围时,它就在RecyclerView顶部
2、item在可见范围内,即在第一个可见item之后,最后一个可见item之前,那么这时scrollToPosition失效,需要手动计算该item的view距离顶部的距离,用scrollBy自行移动到置顶位置
3、item在最后一个可见item之后,用smoothScrollToPosition滑动到可见范围 (此时该item在最后一个位置),再获取该item的view,计算到顶部距离,再监听RecyclerView的滑动,对其进行二次滑动到顶部
贴上该方法主要的实现代码:
//标记是否需要二次滑动private boolean shouldMove;//需要滑动到的item位置private int mPosition;/*** RecyclerView滑动到指定item函数*/private void smoothMoveToPosition(RecyclerView recyclerView, final int position) {// 获取RecyclerView的第一个可见位置int firstItem = recyclerView.getChildLayoutPosition(recyclerView.getChildAt(0));// 获取RecyclerView的最后一个可见位置int lastItem = recyclerView.getChildLayoutPosition(recyclerView.getChildAt(mRecyclerView.getChildCount() - 1));if (position < firstItem) {// 指定item在第一个可见item之前recyclerView.smoothScrollToPosition(position);} else if (position <= lastItem) {// 指定item在可见范围内,即在第一个可见item之后,最后一个可见item之前int position = position - firstItem;if (position >= 0 && position < recyclerView.getChildCount()) {// 计算指定item的view到顶部的距离int top = recyclerView.getChildAt(position).getTop();// 手动滑动到顶部recyclerView.smoothScrollBy(0, top);}} else {// 指定item在最后一个可见item之后,用smoothScrollToPosition滑动到可见范围// 再监听RecyclerView的滑动,对其进行二次滑动到顶部recyclerView.smoothScrollToPosition(position);mPositon = position;shouldMove = true;}}…………/*** 监听RecyclerView的滑动,对需要进行二次滑动的item进行滑动**/mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollStateChanged(RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);if ( shouldMove && RecyclerView.SCROLL_STATE_IDLE == newState) {shouldMove = false;smoothMoveToPosition(mRecyclerView, mPosition);}}});
本文推荐的另外一种处理方式
通过上面的代码可以看出来,这种处理方式比较麻烦,而且处理逻辑需要分成两块,并不够直观。因此点开源码,发现实际上RecyclerView在用smoothScrollToPosition函数时,是创建了一个LinearSmoothScroller:

再继续点开看:

一进入文件就发现了SNAP_TO_START这个参数,注释意思是,将子view与父view左对齐或顶部对齐,其中是左对齐还是顶部对齐,是根据LayoutManager是horizontal还是vertical决定,因此重写LinearSmoothScroller,设置该参数即可实现置顶。
public class TopSmoothScroller extends LinearSmoothScroller {TopSmoothScroller(Context context) {super(context);}@Overrideprotected int getHorizontalSnapPreference() {return SNAP_TO_START;}@Overrideprotected int getVerticalSnapPreference() {return SNAP_TO_START;  // 将子view与父view顶部对齐}
}
之后获取RecyclerView的LayoutManager,调用startSmoothScroll即可
final TopSmoothScroller mTopScroller = new TopSmoothScroller(this);
mTopScroller.setTargetPosition(position);
mRecyclerView.getLayoutManager.startSmoothScroll(mTopScroller);

用startSmoothScroll实现RecyclerView滚动到指定位置并置顶,含有动画。相关推荐

  1. RecyclerView滚动到指定位置

    滚动到指定位置 recyclerView.scrollToPosition(position); 平滑滚动到指定位置 recyclerView.smoothScrollToPosition(posit ...

  2. recyclerview滚动到指定条目

    android recyclerview滚动到指定条目 自从android5.0推出RecyclerView以后,RecyclerView越来越受广大程序员的热爱了!大家都知道RecyclerView ...

  3. vue 点击div 获取位置_vue 点击元素滚动到指定位置

    {{item}} {{item}} data() {return{ navgator: ['列表A','列表B','列表C','列表D', ], navgatorIndex:0, listBox: [ ...

  4. 监听某个区域滚动_监听页面滚动及滚动到指定位置

    一.原生js通过window.onscroll监听 window.onscroll = function() { //为了保证兼容性,这里取两个值,哪个有值取哪一个 //scrollTop就是触发滚轮 ...

  5. ios开发之--令UITableView滚动到指定位置

    这个应用场景还是挺多的,代码如下: //获取到需要跳转位置的行数 NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:10 inSe ...

  6. 【小程序】滚动到指定位置

    点击按钮滚动到页面内的指定位置. wxml <view class="btn" catchtap="scrollToElement">去报名< ...

  7. vue 网页滚动到指定位置显示动画效果

    大部分的网页,在滚动到一定位置的时候,当前区块的文案或者图片有一些飞入,淡入淡出,向上划入的动画效果 //向上划入样式 .boxUp {transform: translateY(0%) !impor ...

  8. js控制页面滚动到指定位置,js中scrollIntoView()的用法

    js中scrillIntoView()的用法--页面滚动到指定位置 最近遇到一个问题,在一个页面上,点击某个按钮时,滚动到页面的某一位置. 如图: 如果是我写的话,我可能会先获取滚动到的元素,然后获取 ...

  9. div滚动到指定位置 vue_Vue列表实现滚动到指定位置样式改变

    这个需求大概是这样子: 我做的一个聊天Demo,在搜索框搜索用户,可以滚动到指定的用户.然后成选中状态. 这是目前状态,我搜索南宫仆射 ,想要下面的用户列表直接滚动到 南宫仆射 并改变CSS样式. 查 ...

最新文章

  1. python 调用函数内部参数
  2. tomcat7 内存溢出 java.lang.OutOfMemoryError: Java heap space
  3. OAF_EO系列2 - Validation数据校验验证机制(概念)
  4. 管道( Pipeline )模型--示例
  5. 微盟耗时 145 个小时弥补删库,血亏 1.5 亿元!
  6. xpath-了解xpath语言-下载xpath_helper工具
  7. CV Papers|计算机视觉论文推荐周报20200502期
  8. 如何给数组用fill函数和memset函数给数组赋初值
  9. unbuntu下 配置vim 详解
  10. FireFox2和FireFox3共存解决方案(附完整图解)
  11. MCMC算法原理及其实例
  12. 轻轻松松背单词软件测试,Englishfield词汇记忆与测试
  13. 简述igp和egp_路由协议的常见分类——GGP、EGP和IGP介绍
  14. 微信小程序中使用ECharts实现报表图表展示
  15. 《UniDAC 基础》 【菜头】 翻译 (之一)
  16. React学习中的一个小实战(智能社)
  17. 【安卓笔记】wallpaper设置系统主页墙纸的一种方法
  18. 装机员 Ghost Win7 Sp1 64位装机9月版
  19. 网络安全及网络安全评估的脆弱性分析
  20. 实现单片机脉宽测量功能

热门文章

  1. 家居灯光控制系统设计 android,基于Android的室内照明控制系统设计与实现
  2. 数据结构 堆中的路径(最小堆)
  3. Acwing 1085. 不要62
  4. Zju2112 Dynamic Rankings(树状数组套可持久化权值线段树)
  5. [COCI 2018#5]Parametriziran
  6. YBTOJ:运动积分(trie树)
  7. P7516-[省选联考2021A/B卷]图函数【bfs】
  8. 【2018.3.24】模拟赛之三-ssl2547 圆环【数论】
  9. ssl1203-书的复制【dp】
  10. 【LCT】大融合(luogu 4219)