Android 仿电商app商品详情页按钮浮动效果
1、效果图如下:

这效果用户体验还是很酷炫,今天我们就来讲解如何实现这个效果。
2、分析
为了方便理解,作图分析

如图所示,整个页面分为四个部分:
1、悬浮内容,floatView
2、顶部内容,headView
3、中间内容,与悬浮内容相同,middleView
4、商品详情展示页面,detailView
因为页面内容高度会超出屏幕,所以用Scrollview实现滚动,悬浮view与scrollview同级,都在一个帧布局或者相对布局中。
当y方向的滚动距离小于中间的内容middleView到顶部的距离时,middleView理所当然的会随这页面向上滑动而消失,我们显示悬浮view,从而实现middleView一直卡在顶部的效果。
当y方向滚动距离大于中间的内容middleView容到顶部的距离时,悬浮view隐藏即可。
通过分析,我们发现只要知道scrollview的滚动距离和middleView到顶部的高度即可。至此将复杂的交互特效变成了俩个简单的api。
3、第一种方法实现
3.1 获取middleView的到父容器顶部的距离
tv_title.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
mTitleTopAndHeight = tv_title.getTop(); tv_title.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
在activity的oncreate()中直接通过view的getTop()方法获取到view的高度会返回0,这是因为此时view还没有绘制到界面,所以我们采用上面的方法给view设置监听获取,由于可能发生多次绘制,所以最后记得移除监听事件。
以下代码同样可以获取:
tv_title.post(new Runnable()
{
@Override
public void run()
{
mTitleTopAndHeight = tv_title.getTop();
}
});
利用post方法将操作放到队列中,等系统布局完成后执行队列中的事件,同样可以获取到正确的view的top值。
3.2 获取垂直方向滚动距离
在Scrollview的父类View中有个内容变化的方法onScrollChanged(),虽然该方法是protect的外部不可调用,但是在内部,当scrollview滚动时就会执行该方法,所以我们自定义一个MyScrollView在onScrollChanged()通过回调将滚动的距离传递给外部。
自定义scrollview完整代码如下:
public class MyScrollView extends ScrollView
{
private OnScrollListener mOnScrollListener; /**
* 是否用户手指触摸滑动
*/
private boolean mIsTouch = false; public MyScrollView(Context context)
{
this(context, null);
} public MyScrollView(Context context, AttributeSet attrs)
{
this(context, attrs, );
} public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
} @Override
protected void onScrollChanged(int l, int t, int oldl, int oldt)
{
super.onScrollChanged(l, t, oldl, oldt); if (mOnScrollListener != null)
{
mOnScrollListener.onScroll(t, mIsTouch ? OnScrollListener.SCROLL_STATE_TOUCH_SCROLL : OnScrollListener.SCROLL_STATE_FLING);
}
} @Override
public boolean onTouchEvent(MotionEvent ev)
{
switch (ev.getAction())
{
case MotionEvent.ACTION_MOVE:
mIsTouch = true; break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsTouch = false; break;
} return super.onTouchEvent(ev);
} public void setOnScrollListener(OnScrollListener onScrollListener)
{
mOnScrollListener = onScrollListener;
} public interface OnScrollListener
{
/**
* 用户手指拖动滚动
*/
int SCROLL_STATE_TOUCH_SCROLL = 0x0; /**
* 惯性滑行滚动
*/
int SCROLL_STATE_FLING = 0x1; /**
* 滚动时的回调
*
* @param scrollY Y方向滚动的距离
* @param scroll_state 当前滚动状态:自由滚动或者手势拖动滚动
*/
void onScroll(int scrollY, int scroll_state);
}
}
3.3 使用
在acitivity中给scrollview设置自定义滚动监听事件即可
mScrollView.setOnScrollListener(new MyScrollView.OnScrollListener()
{
@Override
public void onScroll(int scrollY, int state)
{
Log.d("onScroll: ", scrollY + "" + "----------- state:" + state); if (scrollY <= mTitleTopAndHeight)
{
tv_float.setVisibility(View.INVISIBLE);
} else
{
tv_float.setVisibility(View.VISIBLE);
}
}
});
这样,通过垂直方法的滚动值来控制floatView的显示隐藏,
tv_float.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
mScrollView.onTouchEvent(event);
return false;
}
});
给悬浮view设置触摸监听,将用户手势传递给scrollView,这样用户滑动悬浮view时,内容区域也可以跟随滚动。
下面是布局代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
> <com.example.qike.scrolltitle.MyScrollView
android:id="@+id/sv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"> <TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:text="商品图片"/> <TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#a3c"
android:gravity="center"
android:text="标题view"/> <TextView
android:layout_width="match_parent"
android:layout_height="600dp"
android:background="#a2bb"
android:gravity="center"
android:text="详情页面"/>
</LinearLayout>
</com.example.qike.scrolltitle.MyScrollView> <TextView
android:id="@+id/tv_float"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#a3c"
android:gravity="center"
android:text="标题view"
android:visibility="invisible"/> </RelativeLayout>
4、第二种方式
本方法与第一种方式的区别就是获取滚动位置的方法不同,该方法更简单一些:
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener()
{
@Override
public void onScrollChanged()
{
int scrollY = mScrollView.getScrollY();
if (scrollY <= mTitleTopAndHeight)
{
tv_float.setVisibility(View.INVISIBLE);
} else
{
tv_float.setVisibility(View.VISIBLE);
}
}
});
可能有读者要问,既然有这种简单的方法直接设置监听,为什么还介绍第一种方法。细心的你可能已经发现,在第一种方法中,我在自定义的监听事件中,还回调了代表当前回调状态的参数statue,因为很多app,在用户手动拖动滚动跟惯性滚动的处理是不能的。比如淘宝商品详情页面,当达到边界值中间view的top值时,只有用户手动拖动一段距离后才会拉出底部的详情类容,而惯性滑动的话只会停在那里。
5、总结
以上就是关于安卓实现按钮随着上下滚动而悬浮顶在固定位置的方法,希望本文的内容对大家开发Android能有所帮助。
Android 仿电商app商品详情页按钮浮动效果的更多相关文章
- Android跳转淘宝、京东APP商品详情页
import Android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; imp ...
- 自己定义ViewGroup实现仿淘宝的商品详情页
近期公司在新版本号上有一个须要. 要在首页加入一个滑动效果, 详细就是仿照X宝的商品详情页, 拉到页面底部时有一个粘滞效果, 例如以下图 X东的商品详情页,假设用户继续向上拉的话就进入商品图文描写叙述 ...
- 微信小程序电商实战-商品详情(上)
先看一下今天要实现的小程序商品详情页吧! 商品详情.gif 本期我们要实现小程序商品详情页的头部标题.头部轮播.商品详情浮动按钮和商品内页布局. 一.设置头部标题 如上图所示,头部标题是商品详情 ...
- android仿今日头条App、多种漂亮加载效果、选择器汇总、记事本App、Kotlin开发等源码
Android精选源码 android漂亮的加载效果 android各种 选择器 汇总源码 Android仿bilibili搜索框效果 Android记事本app.分类,涂鸦.添加图片或者其他附件 仿 ...
- 仿京东淘宝商品详情页属性选择js效果
在网上找了好久发现都不符合要求就自己摸索写了一个,用到了linq.js这个linq to js 扩展,不然用纯JS遍历json查询要死人啊 demo:http://123.207.28.46:8086 ...
- Android仿淘宝继续上拉进入商品详情页的效果,使用双Fragment动画切换;
仿淘宝继续上拉进入商品详情页的效果,双Fragment实现: 动画效果: slide_above_in.xml <?xml version="1.0" encoding=&q ...
- 电商 APP 下单页(俗称车2) 业务流程概要设计
购物车是电商APP的一个关键功能点,一般购物车包含 3-4 个页面,分别是: 1.购物车的商品列表页 2.商品下单页 3.订单付款页面 4.订单付款成功页面 由于现有购物车逻辑相对混乱,这里重新整理一 ...
- Android点击跳转到淘宝的某一商品详情页或者某一店铺页面
最近项目的有个需求是点击购买资料按钮进入淘宝界面,简单分析一下,如果用户手机有淘宝就打开淘宝的页面,没有的话也可以选择使用webView进行展示,还是使用手机浏览器进行展示. 判断有无淘宝的代码就不贴 ...
- Android通用框架设计与完整电商APP开发系列文章
作者|傅猿猿 责编|Javen205 有福利 有福利 有福利 鸣谢 感谢@傅猿猿 邀请写此系列文章 Android通用框架设计与完整电商APP开发 课程介绍 [导学视频] [课程详细介绍] 以下是部分 ...
随机推荐
- netty+mqtt
package io.mqtt.server; import io.mqtt.tool.ConfigService;import io.netty.bootstrap.ServerBootstrap; ...
- POJ 3690 Constellations (哈希)
题意:给定上一n*m的矩阵,然后的t个p*q的小矩阵,问你匹配不上的有多少个. 析:可以直接用哈希,也可以用AC自动机解决. 代码如下: #pragma comment(linker, "/ ...
- ES Docs-3:Modifying Data
Modifying Data Indexing/Replacing Documents curl -XPUT 'localhost:9200/customer/external/1?pretty' - ...
- 实用掌中宝--HTML&CSS常用标签速查手册 PDF扫描版
实用掌中宝--HTML&CSS常用标签速查手册 内容推荐: 本书第一篇以语法和实例相结合的形式,详细讲解了HTML语言中各个元素及其属性的作用.语法和显示效果:第二篇从CSS基本概念开始,分别 ...
- 托管调试助手 "PInvokeStackImbalance":的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管
在C#中一定要检查引用时的数据类型 WinAPI 的数据类型 默认是32位的,但是引用时外部的是 Long类型默认是64位的.所以引用时需要将 long 改为 int 型. 参照 http://blo ...
- .net core关于跨域及Cookie的部分问题
一.如何跨域 1.情景描述 目前有A站点和B站点.A站点有一个API接口为UserData接口,B站点希望可以通过ajax请求来获取A站点该接口数据. 2.后端修改 首先在ConfigureServi ...
- C#之数据类型转换
前言 在C#中学习中,像在VB学习的时候一样,我们会接触到很多种数据类型,但是VB中在用数据类型的时候,我们会考虑这个数据要求多大的内存,或者说有时候为了满足很少的大内存事件,而狠心分配给它较大 ...
- hdu 4388 Stone Game II
Stone Game II HDU - 4388 题目大意: 给出n堆物品,每堆物品都有若干件,现在A和B进行游戏,每人每轮操作一次,按照如下规则: 1. 任意选择一个堆,假设该堆有x个物品,从中选择 ...
- NAT模式下设置 虚拟机linux(Centos7) 联网
第一步 设置虚拟机网络为NAT模式 第二步 设置虚拟机网络配置 首先执行 cd /etc/sysconfig/network-scripts 之后VI 编辑 ifcfg-ens33(根据实际情况来 基 ...
- [BJWC2008]雷涛的小猫 dp
题目背景 原最大整数参见P1012 题目描述 雷涛同学非常的有爱心,在他的宿舍里,养着一只因为受伤被救助的小猫(当然,这样的行为是违反学生宿舍管理条例的).在他的照顾下,小猫很快恢复了健康,并且愈发的 ...