RecyclerView实现横向滑动后自动选中条目,点击其它条目自动移动到中间位置并选中;

横向的列表就是上面的效果,下面是动图;

效果就是这样的 , 有当前选中回调 , 也可以设置当前选中的条目;

代码无封装,看着更直观;

  • 获取中间位置,这个位置就是Item需要停留到的位置;
  • 滑动后计算出距离中间位置最近的一个Item , 然后让此Item滑动到居中位置;
  • 点击其它条目时 , 计算此条目距离中间的位置 , 然后滑动到中间;
  • 可以选中第一个条目和最后一个条目 ,使用隐藏的View填充;

1、获取中间位置:

recyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {recyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);}centerToLiftDistance = recyclerView.getWidth() / 2;}});

2、滑动后计算需要移动的Item:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);if (newState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();int fi = linearLayoutManager.findFirstVisibleItemPosition();int la = linearLayoutManager.findLastVisibleItemPosition();Log.i("ccb", "onScrollStateChanged:首个item: " + fi + "  末尾item:" + la);if (isTouch) {isTouch = false;//获取最中间的Item Viewint centerPositionDiffer = (la - fi) / 2;int centerChildViewPosition = fi + centerPositionDiffer; //获取当前所有条目中中间的一个条目索引centerViewItems.clear();//遍历循环,获取到和中线相差最小的条目索引(精准查找最居中的条目)if (centerChildViewPosition != 0){for (int i = centerChildViewPosition -1 ; i < centerChildViewPosition+2; i++) {View cView = recyclerView.getLayoutManager().findViewByPosition(i);int viewLeft = cView.getLeft()+(cView.getWidth()/2);centerViewItems.add(new CenterItemUtils.CenterViewItem(i ,Math.abs(centerToLiftDistance - viewLeft)));}CenterItemUtils.CenterViewItem centerViewItem = CenterItemUtils.getMinDifferItem(centerViewItems);centerChildViewPosition = centerViewItem.position;}scrollToCenter(centerChildViewPosition);}}}@Overridepublic void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {super.onScrolled(recyclerView, dx, dy);}});recyclerView.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {isTouch = true;return false;}});
 private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();/*** 移动指定索引到中心处 , 只可以移动可见区域的内容* @param position*/private void scrollToCenter(int position){position = position < childViewHalfCount ? childViewHalfCount : position;position = position < mAdapter.getItemCount() - childViewHalfCount -1 ? position : mAdapter.getItemCount() - childViewHalfCount -1;LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();View childView = linearLayoutManager.findViewByPosition(position);Log.i("ccb", "滑动后中间View的索引: " + position);//把当前View移动到居中位置if (childView == null) return;int childVhalf = childView.getWidth() / 2;int childViewLeft = childView.getLeft();int viewCTop = centerToLiftDistance;int smoothDistance = childViewLeft - viewCTop + childVhalf;Log.i("ccb", "\n居中位置距离左部距离: " + viewCTop+ "\n当前居中控件距离左部距离: " + childViewLeft+ "\n当前居中控件的一半高度: " + childVhalf+ "\n滑动后再次移动距离: " + smoothDistance);recyclerView.smoothScrollBy(smoothDistance, 0,decelerateInterpolator);mAdapter.setSelectPosition(position);tv.setText("当前选中:" + mDatas.get(position));}

3、点击选中:

 final int fp = position;vh.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {scrollToCenter(fp);Toast.makeText(HorizontalSelectActivity.this, "点击" + mDatas.get(fp), Toast.LENGTH_SHORT).show();}});

4、选中第一个和最后一个:

int childViewHeight = UiUtils.dip2px(HorizontalSelectActivity.this, CHILDVIEWSIZE); //43是当前已知的 Item的高度childViewHalfCount = (recyclerView.getWidth() / childViewHeight + 1) / 2;
if (mDatas == null) mDatas = new ArrayList<>();for (int i = 0; i < 55; i++) {mDatas.add("条目" + i);}for (int j = 0; j < childViewHalfCount; j++) { //头部的空布局mDatas.add(0, null);}for (int k = 0; k < childViewHalfCount; k++) {  //尾部的空布局mDatas.add(null);}
if (TextUtils.isEmpty(mDatas.get(position))){vh.itemView.setVisibility(View.INVISIBLE);}else {vh.itemView.setVisibility(View.VISIBLE);vh.tv.setText(mDatas.get(position));}

OK , 以上只是主要代码和大致思路,全部的代码请移步到

CSDN:https://download.csdn.net/download/qq_35605213/12470655

Github:https://github.com/CuiChenbo/ArcSelectList , 欢迎Star

同理 , 竖直的列表也是这样实现:

Android 横向列表滑动自动选中,RecyclerView实现;相关推荐

  1. android复杂列表滑动卡顿,Android 列表滑动性能优化总结

    列表滑动性能优化是一个老生常谈的问题,最近在做项目的时候又遇到了列表滑动卡顿的问题,我在经过多次思考和尝试后,终于找到了滑动卡顿的元凶,于是将经验总结下来. ViewHolder 先说说最常规的Vie ...

  2. android微信列表滑动删除,Android仿微信对话列表滑动删除效果

    微信对话列表滑动删除效果很不错的,借鉴了github上SwipeListView(项目地址:https://github.com/likebamboo/SwipeListView),在其上进行了一些重 ...

  3. android横向列表控件,Android逆天控件:CircleListView(圆弧形列表)

    背景 近日设计师小姐姐创作能力爆棚,设计了一个狂拽酷炫的效果:星球环绕列表.如下图: image 在拿着板砖去沟通,且看到对方40米长的大刀后,愉快地确认出页面的如下特性: 需要实现一个可围绕圆弧(图 ...

  4. android 横向stepview,一款由Recyclerview打造的步骤控件,支持横向和纵向

    RecyclerviewForStepView 一款由Recyclerview打造的步骤控件,支持横向和纵向 节点的图片和样式可以根据需求改动, 节点的连接线可以自定义.可以添加动画效果,点击事件等 ...

  5. Android横向滚动卡片,RecyclerView+CardView实现横向卡片式滑动效果

    现在来介绍两种控件recyclerview和cardview,并通过实例将它们结合在一起实现一种横向卡片式滑动效果. 1.recyclerview recyvlerview是android sdk 新 ...

  6. android今日头条图片查看效果,图片查看器ImageViewer:轻松实现微信朋友圈、今日头条、横向列表、纵向列表等图片浏览效果...

    ImageViewer 关于 图片浏览器,支持图片手势缩放.拖拽等操作,自定义View的模式显示,自定义图片加载方式,可自定义索引UI与加载进度UI,更加灵活,易于扩展,同时也适用于RecyclerV ...

  7. android listview 滑动条显示_第七十六回:Android中UI控件之RecyclerView基础

    各位看官们,大家好,上一回中咱们说的是Android中UI控件之ListView优化的例子,这一回咱们说的例子是UI控件之RecyclerView.闲话休提,言归正转.让我们一起Talk Androi ...

  8. android 横向滑动日期_移动端横向滑动如何设计?

    所谓的"左右横滑"交互英文名叫做"Horizontal Scrolling Lists",最早可能起源于 Windows Phone 的横向内容滑动设计.用于在 ...

  9. Android横向滑动加载更多的控件的实现---HorizontalScrollSlideView

    Android横向滑动加载更多的控件的实现-HorizontalScrollSlideView 需求 之前公司业务要求做一个横向滑动的,可以加载更多的控件,第一时间想到的就是 RecyclerView ...

最新文章

  1. Python中str.replace()的使用方法
  2. [王晓刚]深度学习在图像识别中的研究进展与展望(转发)
  3. python怎么设置函数超时时间_在python运行时为函数设置超时秒数
  4. SWFKit 3.5 + 注册机
  5. 文献记录(part57)--半监督学习方法
  6. Androidの网络Http之判断是否连接服务器
  7. 《自顶向下网络设计(第3版)》——导读
  8. Oracle]高效的SQL语句之分析函数
  9. vue.js 表单 v-text
  10. 网络运维常见交换机故障
  11. 拜托,别再让我优化大事务了,我的头都要裂开了
  12. 网站推广效率最高的20种办法
  13. 利用服务端session保存用户信息
  14. 拉普拉斯变换转换简表
  15. indesign排版标点挤压_indesign排版标点挤压设置技巧
  16. 2021全国特种设备-G3锅炉水处理模拟考试题库一[安考星]
  17. 用Kivy写一个安卓app
  18. 微软Win10彻底封杀exFAT/FAT32磁盘,格式化只剩NTFS/REFS
  19. h264 : 关于level_idc和Profile_IDC的解释
  20. 从零开始之uboot、移植uboot2017.01(五、board_init_f分析)

热门文章

  1. 【算法练习】85.差的绝对值为 K 的数对数目——计数
  2. 寻找平衡点的俩种方法
  3. 读懂Oracle执行计划(一)
  4. NumPy库(一):数组创建、切片、索引
  5. Python课设实验 之 车票订购系统.(sqlite数据库 储存.)
  6. 电力需求侧管理的概念及政策梳理
  7. AWS re:Invent 科技盛会 英信翻译提供《视频转录和字幕翻译服务》
  8. odoo与企业微信深度集成
  9. H5响应式网站模板下载建站
  10. 前端接收后端返回的集合数据并展示