上一篇文章中有提到界面中嵌套NestedScrollView与Fragment并用,而NestedScrollView是不建议与ListView,RecyclerView嵌套的,虽然有解决滑动冲突的办法,但是ListView与RecyclerView的缓存机制就没有了,大量列表数据界面中这样嵌套还有何意义,但是Fragment中有列表数据需要用到RecyclerView时,如何解决?

更多文章请关注:http://blog.csdn.net/u012216274

本篇就讲述蘑菇街,蜜芽宝贝还有早期淘宝详情界面的实现方式,他们的界面效果都大至相同

一:功能点

1:效果图:

界面中全屏的ScrollView内容滑动,而ScrollView中嵌套水平的Horhorizonscrollview,Banner轮播图,滑动过程中渐渐改变Toolbar的背景, 这里采用NestedScrollView实现

界面上滑类似翻到下一页面,里面再嵌套TabLayout,ViewPager, 而ViewPager中又可以嵌套RecyclerView, ScrollView等滑动控件,滑动到下一页面时显示回到顶部按钮,点击可以跳到上一页面,也可以滑动到上一页面中

2:功能介绍
通过效果图可以看到需要最定义最外层滑动控件(有些类似纵向滑动的ViewPager),google自带的coordinatorlayout控件behavior也可以实现类似这种需求,但是全屏分页面滑动似乎行不通,所以需要定义最外层滑动控件来处理滑动与兼容上面所提到的所有滑动控件的滑动,并支持多点滑动
如果你对定义最上层控件处理滑动冲突与多点滑动不熟悉(后面贴出代码不再详细讲述如何解决滑动冲突问题)
这里链接:Android定义最上层 ViewGroup 并解决多层滑动嵌套冲突与多点触摸滑动

网上有很多种实现方式,但是看过之后觉得兼容与扩展性还是太差,或者有一大堆滑动问题,而真正实现此功能,应该能像Coordinatorlayout那样只需要定义子控件如何滑动或优先滑动规则就行,里面嵌套水平还是纵向还是多层嵌套都能自动适应才算是完美了。

在第一页内容时,上下滑动都是子控件优先,当子控件滑动到底部不能滑动时,最上层控件才执行滑动,并滑动或加速度滑动跳转到第二页面内容, 此时也还是子控件全部优先滑动,子控件不能下滑时,最上层控件执行滑动跳转到第一页面内容

二:功能实现

1:颜色值过渡动画
现在很多APP都喜欢做滑动改变Toolbar背景颜色效果,而这种颜色变化都是根据滑动偏移来计算的.这里就先介绍个颜色过渡类,根据滑动比例获取起始颜色与结束颜色所对应的过渡颜色

/**
* 构造函数** @param startColor  起始颜色值* @param endColor    结束颜色值*/
public ArgbAnimator(int startColor, int endColor) {this.startColor = startColor;this.endColor = endColor;startA = (startColor >> 24) & 0xff;startR = (startColor >> 16) & 0xff;startG = (startColor >> 8) & 0xff;startB = startColor & 0xff;endA = (endColor >> 24) & 0xff;endR = (endColor >> 16) & 0xff;endG = (endColor >> 8) & 0xff;endB = endColor & 0xff;
}/*** 获取动画段中的颜色** @param fraction 0-1.0f* @return*/
public int getFractionColor(float fraction) {if (fraction <= 0)return startColor;if (fraction >= 1.0f)return endColor;return (int) ((startA + (int) (fraction * (endA - startA))) << 24)| (int) ((startR + (int) (fraction * (endR - startR))) << 16)| (int) ((startG + (int) (fraction * (endG - startG))) << 8)| (int) ((startB + (int) (fraction * (endB - startB))));
}

2:最外层ScrollLayout定义,这里直接继承ViewGroup
这里只贴出事件拦截与滑动功能的核心代码,

case MotionEvent.ACTION_MOVE://这里根据android定义的水平与垂直滑动的标准if (mIsBeingDragged) {//Log.i("Log", "isBeingDrag...");return true;}if (mIsUnableToDrag) {//Log.i("Log", "mIsUnableToDrag...");return false;}int index = getPointerIndex(ev, mPointerId);float x = MotionEventCompat.getX(ev, index);float diffX = x - mLastMotionX;float mDiffX = Math.abs(diffX);float y = MotionEventCompat.getY(ev, index);float diffY = y - mLastMotionY;float mDiffY = Math.abs(diffY);int intDiffy = (int) diffY;if (diffY != 0 && (canScroll(intDiffy) || canScroll(this, false, intDiffy, (int) x, (int) y) )) {//注意canScroll只兼容4.0以上的滑动冲突,google工程师有明确标出,如果需要兼容4.0以下版本//可以用我写好的ScrollLayoutCompat类,判断如果4.0以下版本时,用isChildCanScroll判断是否能滑动mLastMotionX = x;mLastMotionY = y;mIsUnableToDrag = true;return false;}if (mDiffX > mTouchSlop && mDiffX * 0.5f > mDiffY) {//没办法,ViewPager要这样写,也许是x轴滑动优先要比Y轴滑动优先低些吧,但是为了兼容ViwPager不得不跟着这么写mIsUnableToDrag = true;} else if (mDiffY > mTouchSlop) {mIsBeingDragged = true;requestParentDisallowInterceptTouchEvent(true);mLastMotionY = diffY > 0? mInitialMotionY + mTouchSlop : mInitialMotionY - mTouchSlop;mLastMotionX = x;}break;/**
* 子控件是否能够滑动,递归查询,这里也是滑动冲突与优先滑动的解决方法* @param v* @param checkV* @param dy* @param x* @param y* @return*/
protected boolean canScroll(View v, boolean checkV, int dy, int x, int y) {if (v instanceof ViewGroup) {final ViewGroup group = (ViewGroup) v;final int scrollX = v.getScrollX();final int scrollY = v.getScrollY();final int count = group.getChildCount();for (int i = count - 1; i >= 0; i--) {// 这里只能兼容到4.0或以上版本,fucking compat,如果要兼容4.0以下滑动,请参考写好的ScrollLayoutCompat类//根据如果小于4.0版本用ScrollLayoutCompat.canScroll方法//  fucking compat//  fucking compat// This will not work for transformed views in Honeycomb+,google源码注释明确指出final View child = group.getChildAt(i);if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight()&& y + scrollY >= child.getTop() && y + scrollY < child.getBottom()&& canScroll(child, true, dy, x + scrollX - child.getLeft(),y + scrollY - child.getTop())) {return true;}}}return checkV && ViewCompat.canScrollVertically(v, -dy);
}

从4.0以后google在控件的水平与纵向滑动规则上都统一拉,所以上层控件只需要要优先判断子控件是否能滑动来决定是否需要拦截事件就可以了,与NestedScroll有些不同,NestedScroll滑动机制是子控件滑动顺便带动上层控件滑动

再是onTouchEvent(MotionEvent event)中的核心代码,这里就只需要处理手指滑动与加速度滑动功能了

case MotionEvent.ACTION_MOVE:int index = getPointerIndex(event, mPointerId);float x = MotionEventCompat.getX(event, index);float y = MotionEventCompat.getY(event, index);float diffY = y - mLastMotionY;float mDiffY = Math.abs(diffY);if (!mIsBeingDragged) {//如果滑动尚未产生if(mDiffY > mTouchSlop) {mIsBeingDragged = true;requestParentDisallowInterceptTouchEvent(true);mLastMotionY = diffY > 0? mInitialMotionY + mTouchSlop : mInitialMotionY - mTouchSlop;mLastMotionX = x;}ViewParent parent = getParent();if (parent != null) {parent.requestDisallowInterceptTouchEvent(true);}}if (mIsBeingDragged) {int intDiffy = (int) diffY;if (performDragY(intDiffy)) {//这里就处理界面跟着手指滑动scrollBy(0, -intDiffy);}mLastMotionY = y;mLastMotionX = x;}break;

3:一些小细节
a:最小加速度单位,这里参考ViewPager源码写法
final float density = context.getResources().getDisplayMetrics().density;
mMinVelocity = (int) (MIN_FLING_VELOCITY * density);
//mMinVelocity = configuration.getScaledMinimumFlingVelocity();
//这里额外定义最小速度单位,用configuration获取的最小单位值比较小,滑动会太敏感

b:前面博客文章讲view生命周期时没有讲述onLayout(boolean changed, int l, int t, int r, int b)方法changed参数,这里作个解释

当界面有滑动偏移并且布局有改变高度时(比如弹出软键盘强制改变布局大小,前面博客文章有讲述),如果不修改滑动偏移值,界面会布局错乱,解决的方法就是通过布局重新测量改变后,根据此参数来判断是否需要重新滑动到计算的新的滑动位置中

/**
* 当线性布局一样布局,  滑动的高度则为第一个item的高度* @param changed* @param l* @param t* @param r* @param b*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {...if (changed) {scrollLayoutChanged();}
}/*** 高度有变化时需要调整滑动偏移位置*/private void scrollLayoutChanged() {if (isClosed()) {scrollTo(0, scrollHeight);}}

小结:这种界面滑动的设计风格比较适用于详情界面中小模块比较多的界面,但是这种也不好的体验就是在上层控件与子控件切换滑动优先时,事件会断掉,要重新滑动,不符合NestedScroll滑动风格,而且现在美团,豌豆荚,淘宝都已经取消了这种效果。无论用哪种滑动风格,滑动控件定义与事件传递原理都是不会变的

最外层控件定义的好,里面嵌套什么控件都不怕有冲突

更多文章请关注:http://blog.csdn.net/u012216274

后面再介绍新的 美团(休闲娱乐详情),淘宝商品详情界面的功能实现
最后附上源码:http://download.csdn.net/detail/u012216274/9835296

仿蘑菇街,蜜芽宝贝,京东商品详情界面,与NestedScroll滑动相关推荐

  1. Android自定义控件-仿淘宝ios客户端天猫商品详情界面

    仿照淘宝和聚美优品,在商品详情页,向上拖动时,可以加载下一页.使用ViewDragHelper,滑动比较流畅. scrollView滑动到底部的时候,再行向上拖动时,添加了一些阻力. 项目地址:htt ...

  2. Android自定义控件-仿淘宝ios客户端天猫商品详情界面动效

    效果图 源码和例子 github:https://github.com/teisun/Android-PullPushScrollView  csdn:http://download.csdn.net ...

  3. 拼多多商品详情采集上传京东店铺(拼多多商品详情接口,京东商品详情接口,整店宝贝采集接口,一键采集宝贝详情接口,无货源商品详情采集接口)代码对接教程

    拼多多商品详情采集上传京东店铺(拼多多商品详情接口,京东商品详情接口,整店宝贝采集接口,一键采集宝贝详情接口,无货源商品详情采集接口)代码对接教程如下: 1.公共参数 名称 类型 必须 描述(接口代码 ...

  4. 拼多多商品详情采集上传京东店铺(拼多多商品详情接口,京东商品详情接口,拼多多整店宝贝采集接口,一键采集拼多多宝贝详情接口,无货源商品详情采集接口)代码对接教程

    拼多多商品详情采集上传京东店铺(拼多多商品详情接口,京东商品详情接口,拼多多整店宝贝采集接口,一键采集拼多多宝贝详情接口,无货源商品详情采集接口)代码对接教程如下: 1.公共参数 名称 类型 必须 描 ...

  5. 通过商品ID获取到京东商品详情页面数据,京东商品详情API接口,京东APP详情接口,可以拿到sku价格,销售价格,优惠价格,主图等页面上面有的数据参数

    一.京东商品详情接口参数说明: 1.通过商品ID和skuID可以拿到淘宝天猫的商品详情的详细sku信息,包括:宝贝ID,规格名称,规格图片,优惠价,原价,快递费用,宝贝标题,宝贝链接,宝贝图片,库存, ...

  6. 京东商品详情页碎碎念

    在之前的两篇文章<构建需求响应式亿级商品详情页>和<京东商品详情页服务闭环实践>已经详细介绍了整个系统的架构设计和实现思路.本篇将介绍下杂七杂八的一些实践: 静态化 突发流量 ...

  7. 使用Python采集京东商品详情数据,并上传到拼多多商城中

    采集场景 打开京东商品详情页(实例网址:https://item.jd.com/100016944073.html ),采集点击不同的参数(颜色.版本等)后得到的数据(商品编号.价格.主图链接等字段会 ...

  8. JavaWeb - 仿小米商城(5):商品详情展示

    JavaWeb - 仿小米商城(5):商品详情展示 1 功能描述 接上篇 JavaWeb - 仿小米商城(4):商品列表形式 本篇博客将分析和实现小米商城商品详情内容的查 询和展示.如下所示: 2 功 ...

  9. 京东商品详情页前端开发宝典

    声明:本位来自京东张开涛的微信公众号(kaitao-1234567),授权CSDN转载,如需转载请联系作者. 作者:周琪力,前端工程师,网络常用昵称「keelii」.在过去的4年里主要负责京东网站商品 ...

最新文章

  1. 列名无效怎么解决_电脑win键失效怎么办? 键盘win键无效的解决办法
  2. 罗美琪和春波特的故事...
  3. mysql 连接校对_教你轻松的掌握 MYSQL连接字符集和校对
  4. 北理工计算机博士怎么样,北京理工大学在职博士的含金量怎么样
  5. 深圳内推 | ​IDEA数字经济研究院招聘NLP算法工程师/算法实习生
  6. linux里创建表空间和用户名,linux下oracle的启动和创建表空间用户
  7. 强烈推荐:程序员必备的两个超级工具,一个是百宝箱,一个是百宝库
  8. auot lisp 选择集处理_离散量的计算机处理63_1Cv6
  9. 安卓3D游戏-神奇宝贝防御战
  10. 一步一步写算法(之链表重合)
  11. 广州“开四停四”交通限行,技术上是如何实现的?
  12. USB key身份认证介绍
  13. 腾达ap设置说明_腾达(Tenda)F3无线信号放大模式(Client+AP)设置 | 192路由网
  14. 2021-11-12 Capturing Car-Following Behaviors by Deep Learning
  15. pubwin2009服务端 修改系统时间方法
  16. 2021十大手表品牌TOP排行榜
  17. html雾霾蓝色号rgb,新型流行色—雾霾蓝
  18. hadoop生态圈的理解
  19. Windows XP运行命令
  20. AI ProCon圆满落幕,五大技术专场精彩瞬间不容错过

热门文章

  1. 100V降压电源芯片 电瓶72V降压DC-DC芯片
  2. 计算机组装与拆解中容易混淆的知识点,教资干货 | 教资笔试中易混淆的知识点整合...
  3. 百胜图CTI拉花比赛上海总决赛
  4. 钉钉(工作协同)应用之前端源码赏析
  5. 欸,自娱自乐的学习必然是缓慢的
  6. 2017年最后两个工作日的年终总结
  7. 常见的股票技术指标到底能赚钱吗?从量化交易的角度告诉你
  8. [学习笔记] windows 下安装nginx和php以及添加yaf框架和redis扩展
  9. 数学分析原理 第2卷 第9版
  10. 中国Linux早期历史的回眸