先上效果图吧:

第一个想到的实现方式是上面使用horizontalScrollview,下面使用Viewpager,经过尝试之后发现二者API有限,不能达到理想效果。几经折腾,最后上下都使用了自定义的RecyclerView。效果图如下:

现在来分析技术点,首先是上下联动,思路是在Recycleview的onScrolled回调方法中操作另一个Recycleview的滑动。

 @Override
public void onScrolled(int dx, int dy) {
super.onScrolled(dx, dy);
sx = sx +dx;
if (scrollViewListener != null && isMark) {
scrollViewListener.onScrollChanged(this, sx, 0);
}
}

其中onScrollChanged方法在主页面中实现

 @Override
public void onScrollChanged(Object scrollView, int x, int y) {
int width1 = CommonUtil.getScreenWidth(this) - DensityUtils.dip2px(this, 60);
int width2 = CommonUtil.getScreenWidth(this);
if (scrollView == rvHead) {
rvFoot.setmark(false);
rvFoot.scrollTo(x * width2 / width1, y);
} else if (scrollView == rvFoot) {
rvHead.setmark(false);
rvHead.scrollTo(x * width1 / width2, y);
}
rvHead.setmark(true);
rvFoot.setmark(true);
}

上下View的滑动速率差即为上下RecyclerView中item的宽度差,上面view中item的宽度为屏幕宽度-60dp,详见对应的adapter。

由于RecyclerView中scrollTo方法没有实现,所以直接想到的是用scroolBy代替,但由于滑动回调返回的是Int值,经过速率差处理后精度丢失,得不到准确值,导致联动效果达不到,痛定思痛,最后还是自己来重写scrollTo方法:

 @Override
public void scrollTo(int x, int y) {
scrollBy(x-sx,0);
}

sx为自己在onScrolled方法中记录,具体见文末给出的源码。

滑动之后,还要进行回调处理,以达到像viewPager那样的回弹效果,具体逻辑在自定义的RecyclerView中的回调方法onScrollStateChanged中实现:

 public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
int mmSelected;
//当控件停止滚动时,获取可视范围第一个item的位置,滚动调整控件以使选中的item刚好处于正中间
int firstVisiblePos = mLayoutManager.findFirstVisibleItemPosition();
if (firstVisiblePos == RecyclerView.NO_POSITION) {
return;
}
Rect rect = new Rect();
mLayoutManager.findViewByPosition(firstVisiblePos).getHitRect(rect);
if (Math.abs(rect.left) > mItemWidth / 2) {
smoothScrollBy(rect.right, 0);
mmSelected = firstVisiblePos + 1;
} else {
smoothScrollBy(rect.left, 0);
mmSelected = firstVisiblePos;
}
if (Math.abs(rect.left) == 0 && mOnSelectListener != null && mmSelected != mSelected) {
mSelected = mmSelected;
mOnSelectListener.onSelect(mSelected);
}
}
}
}

为了让滑动效果更为自然且支持fling效果,本项目还重写了RecyclerView的fling方法,使得每次fling都恰好能滑动整数个item,大致思路为调整fling初始速率,代码如下:

 @Override
public boolean fling(int velocityX, int velocityY) {
int v;
int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
if (Math.abs(velocityX) <= 3*touchSlop) {
return false;
}
mPhysicalCoeff = SensorManager.GRAVITY_EARTH // g (m/s^2)
* 39.37f // inch/meter
* getContext().getResources().getDisplayMetrics().density * 160.0f // pixels per inch
* 0.84f;
int firstVisiblePos = mLayoutManager.findFirstVisibleItemPosition();
if (firstVisiblePos == RecyclerView.NO_POSITION) {
return false;
}
Rect rect = new Rect();
mLayoutManager.findViewByPosition(firstVisiblePos).getHitRect(rect);
double n = getSplineFlingDistance(velocityX) / mItemWidth;
int num = Double.valueOf(n).intValue();
if (velocityX > 0)
v = Double.valueOf(getVelocityByDistance(num * mItemWidth + Math.abs(rect.right)- DensityUtils.dip2px(getContext(), 20))).intValue();
else
v = Double.valueOf(getVelocityByDistance(num * mItemWidth + Math.abs(rect.left)+ DensityUtils.dip2px(getContext(), 20))).intValue();
if (velocityX < 0) {
v = -v;
}
return super.fling(v, velocityY);
}

“京东金融”主页效果 RecyclerView联动的更多相关文章

  1. 【转】京东金融App端链路服务端全链路压测策略

    京东金融移动端全链路压测历时三个月,测试和服务端同学经过无数日日夜夜,通宵达旦,终于完成了移动端链路的测试任务.整个测试有部分涉及到公司敏感数据,本文只对策略部分进行论述. 1.系统架构与策略 在聊性 ...

  2. 双重ScrollView,RecyclerView联动实例

    最近收到一个需求,如图,大家一看,不就是一个简单的表格吗,RecyclerView就搞定了 我一开始也是这么想的,但是当我继续听下去 需求是左边党支部栏目只能上下滑动,之后联动右边下方表格一起上下滑动 ...

  3. RecyclerView联动滑动失败

    RecyclerView联动滑动失败 我们在做Recyclerview联动滑动的时候,就是左边一个RecyclerView右边一个RecyclerView 我们希望左边的RecyclerView可以和 ...

  4. 自己编写的仿京东移动端的省市联动选择JQuery插件

    概述 什么是插件,插件就是即插即用叫插件,很少的配置,很少的代码就可以用都项目里,之所以做这个插件,是因为做了一个省市区的联动,其他项目如果要用怎么办,难道在ctrl+c,ctrl+v?那样做太low ...

  5. 鼠标点击输入框文字消失 value placeholder 以及JQ实现效果 (仿京东的输入框效果)

    鼠标点击输入框文字消失 value实现方法  placeholder实现方法     以及JQ实现placeholder效果 <input type="text" value ...

  6. JS实现操作成功定时回到主页效果

    效果图: 页面代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  7. jquery实现城市选择器效果(二级联动)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. View Controller Transition:京东加购物车效果

    冬天已经过去了,阳光越来越暖洋洋的了.还记得上学的时候,老师总说"春天是播种的季节",而我还没在朋友圈许下什么愿望.一年了,不敢想象回首还能看到点什么,所以勇往直前.当被俗世所扰, ...

  9. js原生淘宝京东宝贝放大镜效果

    js实现商城放大镜效果 效果: 鼠标放上去会有半透明遮罩.右边会有大图片局部图. 鼠标移动时右边的大图片也会局部移动. 技术点: Event Event 是一个事件对象,当一个事件发生后,和当前事件发 ...

随机推荐

  1. MySQL备份---lvm snapshot

    正常安装(缺点要锁表) 1, 创建一个LV(逻辑卷) , 把MySQL的数据目录放到这个LV上 /var/lib/mysql 对这个LV做快照, 从快照备份数据 删除快照 非正常安装 1,创建LV 2 ...

  2. @RequestParam加不加的区别

    感觉@撸码识途 https://www.cnblogs.com/tinyj/p/9786131.html 加上的情况: @RequestMapping("demo") public ...

  3. Spring Boot Runner启动器

    Runner启动器 如果你想在Spring Boot启动的时候运行一些特定的代码,你可以实现接口ApplicationRunner或者CommandLineRunner,这两个接口实现方式一样,它们都 ...

  4. 自动化测试工具selenium webdirver

    看视频学到的,自动化测试工具,可以模拟用户操作,包括输入,点击等操作 新建新文件夹 在命令行执行npm init  ,一路回车,把项目先初始化 安装  npm install selenium-web ...

  5. 关于小窗滑动,父级body也跟随滑动的解决方案(2)

    当第一次写这个问题的时候,并不知道竟然还会写2,而且(1)也并没有解决问题. 也发现,这个问题,真实也困住了很多人,找到了张鑫旭(http://www.zhangxinxu.com/wordpress ...

  6. 使用Let's Encrypt加密你的小站

    介绍 Let's Encrypt是一个免费并且开源的CA,且已经获得Mozilla.微软等主要浏览器厂商的根授信.它极大低降低DV证书的入门门槛,进而推进全网的HTTPS化. Certbot is a ...

  7. 在Ubuntu中搭建KMS服务器

    介绍 基于vlmcsd搭建的KMS服务器. 根据github上的说明,这个工具是用C写的,没有任何依赖,可以直接运行.而且它横跨几乎现在所有的系统平台,如Android, FreeBSD, Solar ...

  8. Linux编程 5 (目录重命名与移动mv,删除文件rm,目录创建mkdir删除rmdir,查看file,cat,more,tail,head)

    一. 文件重命名与移动(mv) 在linux中,重命名文件称为移动(moving).mv命令可以将文件和目录移动到另一个位置或重新命名. 1.1 使用mv重命名 下面在/usr/local下面创建一个 ...

  9. TCP/IP 笔记 - 超时和重传

    TCP协议为了提供可靠的数据传输服务,会启动数据重传来解决下层网络层(IP)可能出现的数据包丢失. 超时重传介绍 TCP重传由两套独立机制来完成重传,基于时间的超时重传(RTO,TCP发送数据时会设置 ...

  10. gitlab+jenkins=自动化构建

    jenkins:运维持续集成工具,靠着丰富的插件挑大梁. gitlab:git代码管理仓库web版,功能强大且丰富. 本文是记录自己工作中从搭建到使用~ 前提是会点git~可以去廖老师的网站学习:ww ...