先上效果图吧:

第一个想到的实现方式是上面使用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. Android开发工程师文集-1 小时学会Widget小组件开发

    前言 大家好,给大家带来Android开发工程师文集-1 小时学会Widget小组件开发的概述,希望你们喜欢 学会用Widget (小组件) Widget小组件很方便,很快捷,可以个性化,自己定制,相 ...

  2. harbor镜像仓库-02-https访问配置

    harbor镜像仓库-02-https访问配置 harbordockerhttps harbor搭建部署参考上一章节 harbor镜像仓库-01-搭建部署 Harbor默认使用http,给harbor ...

  3. Django创建和配置文件

    首先我们随便找一个文件 shift+鼠标右键 点击打开 Powershell 窗口 然后输入命令  django-admin startproject 项目名字 输入cd day   进入这个项目下 ...

  4. 用node.js做cluster,监听异常的邮件提醒服务

    __ __ __ _ __ ____ ____ ____/ /__ _____/ /_ _______/ /____ _____ ___ ____ ___ ____ _(_) / / __ \/ __ ...

  5. docker学习篇(二)---- 基础篇

    引言 在之前的学习中,我知道了docker的三大组件分别是----镜像,容器,仓库.了解了这三个组件也就初步理解了docker.所以我学习了这三个组件,并记录下来. 镜像 docker在运行一个容器时 ...

  6. [视频]K8飞刀 shellcode loader演示教程

    [视频]K8飞刀 shellcode loader演示教程 https://pan.baidu.com/s/1eQ77lPw

  7. 物体检测,Error: maximum box coordinate value is too large

    使用ssd目标检测,出现error:maximum box coordinate value is larger than 1.100000: ] [1.325] 主要原因在于,用labelImg 标 ...

  8. Java RMI HelloWorld

    Java RMI HelloWorld   RMI 远程方法调用. 顾名思义就是可以像调用本地程序方法一样调用远程(其他JVM)的程序方法.   分为3个部分: Stub:中介,代理. 封装了远程对象 ...

  9. Windows下memcache的配置和使用(python)

    1.memcache的安装和配置: 下载memcache  for windows: http://up.2cto.com/2012/0522/20120522094758371.rar 解压到指定目 ...

  10. 从零开始学 Web 之 移动Web(八)Less

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...