1、效果图如下:

这效果用户体验还是很酷炫,今天我们就来讲解如何实现这个效果。

2、分析

为了方便理解,作图分析

如图所示,整个页面分为四个部分:

1、悬浮内容,floatView

2、顶部内容,headView

3、中间内容,与悬浮内容相同,middleView

4、商品详情展示页面,detailView

因为页面内容高度会超出屏幕,所以用Scrollview实现滚动,悬浮viewscrollview同级,都在一个帧布局或者相对布局中。

当y方向的滚动距离小于中间的内容middleView到顶部的距离时,middleView理所当然的会随这页面向上滑动而消失,我们显示悬浮view,从而实现middleView一直卡在顶部的效果。

当y方向滚动距离大于中间的内容middleView容到顶部的距离时,悬浮view隐藏即可。

通过分析,我们发现只要知道scrollview的滚动距离和middleView到顶部的高度即可。至此将复杂的交互特效变成了俩个简单的api。

3、第一种方法实现

3.1 获取middleView的到父容器顶部的距离

  1. tv_title.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
  2. {
  3. @Override
  4. public void onGlobalLayout()
  5. {
  6. mTitleTopAndHeight = tv_title.getTop();
  7.  
  8. tv_title.getViewTreeObserver().removeGlobalOnLayoutListener(this);
  9. }
  10. });

在activity的oncreate()中直接通过view的getTop()方法获取到view的高度会返回0,这是因为此时view还没有绘制到界面,所以我们采用上面的方法给view设置监听获取,由于可能发生多次绘制,所以最后记得移除监听事件。

以下代码同样可以获取:

  1. tv_title.post(new Runnable()
  2. {
  3. @Override
  4. public void run()
  5. {
  6. mTitleTopAndHeight = tv_title.getTop();
  7. }
  8. });

利用post方法将操作放到队列中,等系统布局完成后执行队列中的事件,同样可以获取到正确的viewtop值。

3.2 获取垂直方向滚动距离

Scrollview的父类View中有个内容变化的方法onScrollChanged(),虽然该方法是protect的外部不可调用,但是在内部,当scrollview滚动时就会执行该方法,所以我们自定义一个MyScrollViewonScrollChanged()通过回调将滚动的距离传递给外部。

自定义scrollview完整代码如下:

  1. public class MyScrollView extends ScrollView
  2. {
  3. private OnScrollListener mOnScrollListener;
  4.  
  5. /**
  6. * 是否用户手指触摸滑动
  7. */
  8. private boolean mIsTouch = false;
  9.  
  10. public MyScrollView(Context context)
  11. {
  12. this(context, null);
  13. }
  14.  
  15. public MyScrollView(Context context, AttributeSet attrs)
  16. {
  17. this(context, attrs, );
  18. }
  19.  
  20. public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr)
  21. {
  22. super(context, attrs, defStyleAttr);
  23. }
  24.  
  25. @Override
  26. protected void onScrollChanged(int l, int t, int oldl, int oldt)
  27. {
  28. super.onScrollChanged(l, t, oldl, oldt);
  29.  
  30. if (mOnScrollListener != null)
  31. {
  32. mOnScrollListener.onScroll(t, mIsTouch ? OnScrollListener.SCROLL_STATE_TOUCH_SCROLL : OnScrollListener.SCROLL_STATE_FLING);
  33. }
  34. }
  35.  
  36. @Override
  37. public boolean onTouchEvent(MotionEvent ev)
  38. {
  39. switch (ev.getAction())
  40. {
  41. case MotionEvent.ACTION_MOVE:
  42. mIsTouch = true;
  43.  
  44. break;
  45. case MotionEvent.ACTION_UP:
  46. case MotionEvent.ACTION_CANCEL:
  47. mIsTouch = false;
  48.  
  49. break;
  50. }
  51.  
  52. return super.onTouchEvent(ev);
  53. }
  54.  
  55. public void setOnScrollListener(OnScrollListener onScrollListener)
  56. {
  57. mOnScrollListener = onScrollListener;
  58. }
  59.  
  60. public interface OnScrollListener
  61. {
  62. /**
  63. * 用户手指拖动滚动
  64. */
  65. int SCROLL_STATE_TOUCH_SCROLL = 0x0;
  66.  
  67. /**
  68. * 惯性滑行滚动
  69. */
  70. int SCROLL_STATE_FLING = 0x1;
  71.  
  72. /**
  73. * 滚动时的回调
  74. *
  75. * @param scrollY Y方向滚动的距离
  76. * @param scroll_state 当前滚动状态:自由滚动或者手势拖动滚动
  77. */
  78. void onScroll(int scrollY, int scroll_state);
  79. }
  80. }

3.3 使用

acitivity中给scrollview设置自定义滚动监听事件即可

  1. mScrollView.setOnScrollListener(new MyScrollView.OnScrollListener()
  2. {
  3. @Override
  4. public void onScroll(int scrollY, int state)
  5. {
  6. Log.d("onScroll: ", scrollY + "" + "----------- state:" + state);
  7.  
  8. if (scrollY <= mTitleTopAndHeight)
  9. {
  10. tv_float.setVisibility(View.INVISIBLE);
  11. } else
  12. {
  13. tv_float.setVisibility(View.VISIBLE);
  14. }
  15. }
  16. });

这样,通过垂直方法的滚动值来控制floatView的显示隐藏,

  1. tv_float.setOnTouchListener(new View.OnTouchListener()
  2. {
  3. @Override
  4. public boolean onTouch(View v, MotionEvent event)
  5. {
  6. mScrollView.onTouchEvent(event);
  7. return false;
  8. }
  9. });

给悬浮view设置触摸监听,将用户手势传递给scrollView,这样用户滑动悬浮view时,内容区域也可以跟随滚动。

下面是布局代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. >
  7.  
  8. <com.example.qike.scrolltitle.MyScrollView
  9. android:id="@+id/sv_main"
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content">
  12.  
  13. <LinearLayout
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content"
  16. android:orientation="vertical">
  17.  
  18. <TextView
  19. android:layout_width="match_parent"
  20. android:layout_height="200dp"
  21. android:gravity="center"
  22. android:text="商品图片"/>
  23.  
  24. <TextView
  25. android:id="@+id/tv_title"
  26. android:layout_width="match_parent"
  27. android:layout_height="40dp"
  28. android:background="#a3c"
  29. android:gravity="center"
  30. android:text="标题view"/>
  31.  
  32. <TextView
  33. android:layout_width="match_parent"
  34. android:layout_height="600dp"
  35. android:background="#a2bb"
  36. android:gravity="center"
  37. android:text="详情页面"/>
  38. </LinearLayout>
  39. </com.example.qike.scrolltitle.MyScrollView>
  40.  
  41. <TextView
  42. android:id="@+id/tv_float"
  43. android:layout_width="match_parent"
  44. android:layout_height="40dp"
  45. android:background="#a3c"
  46. android:gravity="center"
  47. android:text="标题view"
  48. android:visibility="invisible"/>
  49.  
  50. </RelativeLayout>

4、第二种方式

本方法与第一种方式的区别就是获取滚动位置的方法不同,该方法更简单一些:

  1. mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener()
  2. {
  3. @Override
  4. public void onScrollChanged()
  5. {
  6. int scrollY = mScrollView.getScrollY();
  7. if (scrollY <= mTitleTopAndHeight)
  8. {
  9. tv_float.setVisibility(View.INVISIBLE);
  10. } else
  11. {
  12. tv_float.setVisibility(View.VISIBLE);
  13. }
  14. }
  15. });

可能有读者要问,既然有这种简单的方法直接设置监听,为什么还介绍第一种方法。细心的你可能已经发现,在第一种方法中,我在自定义的监听事件中,还回调了代表当前回调状态的参数statue,因为很多app,在用户手动拖动滚动跟惯性滚动的处理是不能的。比如淘宝商品详情页面,当达到边界值中间viewtop值时,只有用户手动拖动一段距离后才会拉出底部的详情类容,而惯性滑动的话只会停在那里。

5、总结

以上就是关于安卓实现按钮随着上下滚动而悬浮顶在固定位置的方法,希望本文的内容对大家开发Android能有所帮助。

Android 仿电商app商品详情页按钮浮动效果的更多相关文章

  1. Android跳转淘宝、京东APP商品详情页

    import Android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; imp ...

  2. 自己定义ViewGroup实现仿淘宝的商品详情页

    近期公司在新版本号上有一个须要. 要在首页加入一个滑动效果, 详细就是仿照X宝的商品详情页, 拉到页面底部时有一个粘滞效果, 例如以下图 X东的商品详情页,假设用户继续向上拉的话就进入商品图文描写叙述 ...

  3. 微信小程序电商实战-商品详情(上)

    先看一下今天要实现的小程序商品详情页吧!   商品详情.gif 本期我们要实现小程序商品详情页的头部标题.头部轮播.商品详情浮动按钮和商品内页布局. 一.设置头部标题 如上图所示,头部标题是商品详情 ...

  4. android仿今日头条App、多种漂亮加载效果、选择器汇总、记事本App、Kotlin开发等源码

    Android精选源码 android漂亮的加载效果 android各种 选择器 汇总源码 Android仿bilibili搜索框效果 Android记事本app.分类,涂鸦.添加图片或者其他附件 仿 ...

  5. 仿京东淘宝商品详情页属性选择js效果

    在网上找了好久发现都不符合要求就自己摸索写了一个,用到了linq.js这个linq to js 扩展,不然用纯JS遍历json查询要死人啊 demo:http://123.207.28.46:8086 ...

  6. Android仿淘宝继续上拉进入商品详情页的效果,使用双Fragment动画切换;

    仿淘宝继续上拉进入商品详情页的效果,双Fragment实现: 动画效果: slide_above_in.xml <?xml version="1.0" encoding=&q ...

  7. 电商 APP 下单页(俗称车2) 业务流程概要设计

    购物车是电商APP的一个关键功能点,一般购物车包含 3-4 个页面,分别是: 1.购物车的商品列表页 2.商品下单页 3.订单付款页面 4.订单付款成功页面 由于现有购物车逻辑相对混乱,这里重新整理一 ...

  8. Android点击跳转到淘宝的某一商品详情页或者某一店铺页面

    最近项目的有个需求是点击购买资料按钮进入淘宝界面,简单分析一下,如果用户手机有淘宝就打开淘宝的页面,没有的话也可以选择使用webView进行展示,还是使用手机浏览器进行展示. 判断有无淘宝的代码就不贴 ...

  9. Android通用框架设计与完整电商APP开发系列文章

    作者|傅猿猿 责编|Javen205 有福利 有福利 有福利 鸣谢 感谢@傅猿猿 邀请写此系列文章 Android通用框架设计与完整电商APP开发 课程介绍 [导学视频] [课程详细介绍] 以下是部分 ...

随机推荐

  1. 基于MapReduce的矩阵乘法

    参考:http://blog.csdn.net/xyilu/article/details/9066973文章 文字未得及得总结,明天再写文字,先贴代码 package matrix; import ...

  2. I18N的前后端实现

    所需工具: 1.Vue                https://cn.vuejs.org/ 2.Vue-I18N      https://www.npmjs.com/package/vue-i ...

  3. jquery事件之事件

    事件名 说明 语法 (events 事件类型,data数据,handler 事件处理函数,selector 选择器) blur() 获得失去鼠标光标焦点事件 jQueryObject.blur( [ ...

  4. luogu4168蒲公英(区间众数)

    luogu4168蒲公英(区间众数) 给定n个数,m个区间询问,问每个询问中的众数是什么. 题面很漂亮,大家可以去看一下. 对于区间众数,由于区间的答案不能由子区间简单的找出来,所以似乎不能用树形结构 ...

  5. 洛谷P2294 [HNOI2005]狡猾的商人

    P2294 [HNOI2005]狡猾的商人 题目描述 输入输出格式 输入格式: 从文件input.txt中读入数据,文件第一行为一个正整数w,其中w < 100,表示有w组数据,即w个账本,需要 ...

  6. 洛谷P1342 请柬

    P1342 请柬 题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学 ...

  7. [Xcode 实际操作]四、常用控件-(1)UIButton控件的使用

    目录:[Swift]Xcode实际操作 本文将演示按钮控件的使用,按钮是用户界面中最常见的交互控件 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import U ...

  8. gitlab web端使用

    https://jenkins.io/zh/doc/pipeline/tour/getting-started/ http://www.cnblogs.com/cheng95/p/6542036.ht ...

  9. 使用命令安装vue插件

    使用命令npm install element-ui --save-dev 安装element-ui. --save-dev表示自动添加配置依赖到package.json文件的devDependenc ...

  10. ContOS7分区并挂载硬盘(gpt)

    parted fdisk [只支持MSDOS分区布局] parted [支持MSDOS.GPT分区布局] 分区有三个步骤: 第一个步骤就是用分区工具进行分区 第二个步骤就是创建文件系统(也就是格式化) ...