商品详情页上拉查看详情开源库
商品详情页上拉查看详情
目录介绍
- 01.该库介绍
- 02.效果展示
- 03.如何使用
- 04.注意要点
- 05.优化问题
- 06.部分代码逻辑
- 07.参考案例
01.该库介绍
- 模仿淘宝、京东、考拉等商品详情页分页加载的UI效果。可以嵌套RecyclerView、WebView、ViewPager、ScrollView等等。
- 项目地址:github.com/yangchong21…
02.效果展示
2.1 使用SlideLayout效果
2.2 使用SlideAnimLayout带有加载动画效果
03.如何使用
3.1 第一种,直接上拉加载分页【SlideLayout有两个子ChildView】
- SlideDetailsLayout有两个子ChildView:一个是商品页layout,一个是详情页layout
- 在布局中
<com.ycbjie.slide.SlideLayoutandroid:id="@+id/slideDetailsLayout"android:layout_width="match_parent"android:layout_height="match_parent"app:default_panel="front"app:duration="200"app:percent="0.1"><!--商品布局--><FrameLayoutandroid:id="@+id/fl_shop_main"android:layout_width="match_parent"android:layout_height="wrap_content"/><!--分页详情webView布局--><include layout="@layout/include_shop_detail"/></com.ycbjie.slide.SlideLayout> 复制代码
- 在代码中
mSlideDetailsLayout.setOnSlideDetailsListener(new SlideLayout.OnSlideDetailsListener() {@Overridepublic void onStatusChanged(SlideLayout.Status status) {if (status == SlideLayout.Status.OPEN) {//当前为图文详情页Log.e("FirstActivity","下拉回到商品详情");} else {//当前为商品详情页Log.e("FirstActivity","继续上拉,查看图文详情");}} });//关闭商详页 mSlideDetailsLayout.smoothClose(true); //打开详情页 mSlideDetailsLayout.smoothOpen(true); 复制代码
3.2 第一种,上拉加载有动画效果,然后展示分页【SlideAnimLayout有三个子ChildView】
- SlideAnimLayout有三个子ChildView:一个是商品页layout,一个是上拉加载动画layout,一个是详情页layout
- 在布局中
<com.ycbjie.slide.SlideAnimLayoutandroid:id="@+id/slideDetailsLayout"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"app:default_panel="front"app:duration="200"app:percent="0.1"><!--商品布局--><FrameLayoutandroid:id="@+id/fl_shop_main2"android:layout_width="match_parent"android:layout_height="match_parent"/><!--上拉加载动画布局--><LinearLayoutandroid:id="@+id/ll_page_more"android:orientation="vertical"android:background="@color/colorAccent"android:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/iv_more_img"android:layout_width="40dp"android:layout_height="40dp"android:rotation="180"android:layout_gravity="center_horizontal"android:src="@mipmap/icon_details_page_down_loading" /><TextViewandroid:id="@+id/tv_more_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginBottom="25dp"android:gravity="center"android:text="测试动画,继续上拉,查看图文详情"android:textSize="13sp" /></LinearLayout><!--分页详情webView布局--><include layout="@layout/include_shop_detail"/></com.ycbjie.slide.SlideAnimLayout> 复制代码
- 在代码中
mSlideDetailsLayout.setScrollStatusListener(new SlideAnimLayout.onScrollStatusListener() {@Overridepublic void onStatusChanged(SlideAnimLayout.Status mNowStatus, boolean isHalf) {if(mNowStatus== SlideAnimLayout.Status.CLOSE){//打开if(isHalf){mTvMoreText.setText("释放,查看图文详情");mIvMoreImg.animate().rotation(0);LoggerUtils.i("onStatusChanged---CLOSE---释放"+isHalf);}else{//关闭mTvMoreText.setText("继续上拉,查看图文详情");mIvMoreImg.animate().rotation(180);LoggerUtils.i("onStatusChanged---CLOSE---继续上拉"+isHalf);}}else{//打开if(isHalf){mTvMoreText.setText("下拉回到商品详情");mIvMoreImg.animate().rotation(0);LoggerUtils.i("onStatusChanged---OPEN---下拉回到商品详情"+isHalf);}else{//关闭mTvMoreText.setText("释放回到商品详情");mIvMoreImg.animate().rotation(180);LoggerUtils.i("onStatusChanged---OPEN---释放回到商品详情"+isHalf);}}} });//关闭商详页 mSlideDetailsLayout.smoothClose(true); //打开详情页 mSlideDetailsLayout.smoothOpen(true); 复制代码
04.注意要点
- 针对SlideDetailsLayout仅获取子节点中的前两个View
- 其中第一个作为Front,即商品页;第二个作为Behind,即图文详情WebView页面。具体看代码:
@Override protected void onFinishInflate() {super.onFinishInflate();final int childCount = getChildCount();if (1 >= childCount) {throw new RuntimeException("SlideDetailsLayout only accept child more than 1!!");}mFrontView = getChildAt(0);mBehindView = getChildAt(1);if(mDefaultPanel == 1){post(new Runnable() {@Overridepublic void run() {//默认是关闭状态的smoothOpen(false);}});} } 复制代码
- 针对SlideAnimLayout仅获取子节点中三个View,且第二个为动画节点View
- 其中第一个作为Front,即商品页;第二个作为anim,即上拉动画view。第三个作为Behind,即图文详情WebView页面。具体看代码:
@Override protected void onFinishInflate() {super.onFinishInflate();final int childCount = getChildCount();if (1 >= childCount) {throw new RuntimeException("SlideDetailsLayout only accept childs more than 1!!");}mFrontView = getChildAt(0);mAnimView = getChildAt(1);mBehindView = getChildAt(2);mAnimView.post(new Runnable() {@Overridepublic void run() {animHeight = mAnimView.getHeight();LoggerUtils.i("获取控件高度"+animHeight);}});if(mDefaultPanel == 1){post(new Runnable() {@Overridepublic void run() {//默认是关闭状态的smoothOpen(false);}});} } 复制代码
05.优化问题
- 异常情况保存状态
@Override protected Parcelable onSaveInstanceState() {SavedState ss = new SavedState(super.onSaveInstanceState());ss.offset = mSlideOffset;ss.status = mStatus.ordinal();return ss; }@Override protected void onRestoreInstanceState(Parcelable state) {SavedState ss = (SavedState) state;super.onRestoreInstanceState(ss.getSuperState());mSlideOffset = ss.offset;mStatus = Status.valueOf(ss.status);if (mStatus == Status.OPEN) {mBehindView.setVisibility(VISIBLE);}requestLayout(); } 复制代码
- 当页面销毁的时候,移除listener监听,移除动画资源
@Override protected void onDetachedFromWindow() {super.onDetachedFromWindow();setScrollStatusListener(null);setOnSlideStatusListener(null);if (animator!=null){animator.cancel();animator = null;} } 复制代码
06.部分代码逻辑
6.1 如何实现ScrollView在最顶部或者最底部的时候,不消费事件
- 具体逻辑在dispatchTouchEvent分发事件中,当滑动到顶部或者底部的时候,则直接让父View消费事件。其他情况是自己是将事件会向上返还给View的父节点。
@Override public boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:downX = ev.getX();downY = ev.getY();//如果滑动到了最底部,就允许继续向上滑动加载下一页,否者不允许//如果子节点不希望父进程拦截触摸事件,则为true。getParent().requestDisallowInterceptTouchEvent(true);break;case MotionEvent.ACTION_MOVE:float dx = ev.getX() - downX;float dy = ev.getY() - downY;boolean allowParentTouchEvent;if (Math.abs(dy) > Math.abs(dx)) {if (dy > 0) {//位于顶部时下拉,让父View消费事件allowParentTouchEvent = isTop();} else {//位于底部时上拉,让父View消费事件allowParentTouchEvent = isBottom();}} else {//水平方向滑动allowParentTouchEvent = true;}getParent().requestDisallowInterceptTouchEvent(!allowParentTouchEvent);break;default:break;}return super.dispatchTouchEvent(ev); } 复制代码
6.2 如何实现商品页和详情页之间的滑动,如何处理上拉加载控件的动画效果
- SlideAnimLayout有三个子ChildView:一个是商品页layout,一个是上拉加载动画layout,一个是详情页layout
- 通过onInterceptTouchEvent进行事件拦截后,在onTouchEvent方法中对触摸信息做进一步处理可以实现竖直方向的滑动
- 当商品页ScrollView滑动到底部时,则直接让父View消费事件,该父View也就是SlideAnimLayout
- 在onInterceptTouchEvent中,当打开详情页后(也就是CLOSE状态),向下拉动,当y轴滑动位移绝对值大于触摸移动的像素距离,并且当y轴滑动位移大于0,则拦截事件分发自己消费事件
- 在onInterceptTouchEvent中,当关闭详情页后(也就是OPEN状态),向上拉动,当y轴滑动位移绝对值大于触摸移动的像素距离,并且当y轴滑动位移小于0,则拦截事件分发自己消费事件
- 当处在商品页时,向上拉动;或者处于详情页时,向下拉动,在拉动过程中去改变mSlideOffset值,并且调用requestLayout()方法去绘制
- 在屏幕区域滑动两个面板只需要改变两个面板在y轴方向的位移(有正负方向)即可。滑动的标尺是控件相对于Top的移动,且所有的位移计算都是基于该标尺。在切换面板时只需要知道对应的offset值即可……
- 如何处理上拉加载控件的动画效果
- 添加一个listener监听,可以监听到状态,以及是否达到一半距离,主要是和offset比较,当到达一半距离的时候,这个时候用属性动画将箭头view旋转180度即可实现。
- 既然要监听滑动距离,则首先要获取该加载控件的高度animHeight,那么在哪里获取比较合适呢?可以在onFinishInflate()方法中,用post形式获取控件高度。
- 那么如何使滑动生效,并且看上去比较连贯
- 自定义布局中有非常重要的两个环节onMeasure(测量)和onLayout(布局)。测量决定了View的所占的大小,布局决定了View所处的位置。实现滑动的关键思路就在这里,我们在onLayout方法中根据通过onInterceptTouchEvent、onTouchEvent得到的滑动信息进行计算而得到布局的位置信息,并把这个位置信息设置到子View上面即可实现滑动。
- 滑动后松开手指如何实现滚动效果
- 也就是说,当处在商品页时,向上拉动,拉动位移大于一半时,松开手指,则直接滑动到下一页详情页页面
- 具体逻辑在finishTouchEvent方法中,它主要是记录offset值,以及close或open状态下视图的高度,还有是否发生切换变化
- 最后开启动画,在动画过程中添加动画update的监听,在该方法中去requestLayout()控件,这样就达到滚动效果了。动画滚动结束后,如果是open状态并且是第一次显示,则设置详情页控件可见。
- 如何使滚动效果比较自然,或者如何调整滚动时长
- 可以自定义设置时间,直接在布局中设置……
07.参考案例
- 感谢下面大佬的开源案例
- github.com/jeasonlzy/V…
- github.com/hexianqiao3…
- github.com/cnbleu/Slid…
08.其他更多
01.关于博客汇总链接
- 1.技术博客汇总
- 2.开源项目汇总
- 3.生活博客汇总
- 4.喜马拉雅音频汇总
- 5.其他汇总
02.关于我的博客
- 我的个人站点:www.yczbj.org,www.ycbjie.cn
- github:github.com/yangchong21…
- 知乎:www.zhihu.com/people/yczb…
- 简书:www.jianshu.com/u/b7b2c6ed9…
- csdn:my.csdn.net/m0_37700275
- 喜马拉雅听书:www.ximalaya.com/zhubo/71989…
- 开源中国:my.oschina.net/zbj1618/blo…
- 泡在网上的日子:www.jcodecraeer.com/member/cont…
- 邮箱:yangchong211@163.com
- 阿里云博客:yq.aliyun.com/users/artic… 239.headeruserinfo.3.dT4bcV
- segmentfault头条:segmentfault.com/u/xiangjian…
- 掘金:juejin.im/user/593943…
项目地址:github.com/yangchong21…
商品详情页上拉查看详情开源库相关推荐
- Android仿京东、淘宝商品详情页上拉查看更多详情
老规矩,先上图,没图说个J8 高清原图GIF图,请移步:https://github.com/kangkanger/SlideSeeMoreLayout/blob/master/screenshots ...
- 淘宝产品详情页 上拉加载图片详情 效果实现
希望有建议可以一起交流. 不累赘多余语言,看效果图: 代码如下 #import "ViewController.h" #import "UIView+Category.h ...
- 仿淘宝商品浏览界面, 向上拉查看详情
最新项目中有展示类似淘宝商品详情的功能,主要实现 向上拉查看详情,百度一搜,发现有大神已经实现这个效果了 http://blog.csdn.net/zhongkejingwang/article/d ...
- Android 仿淘宝商品详情页下拉足迹Demo
DropDownMultiPager 仿淘宝等商品详情页下拉足迹效果SimpleDemo 可colne之后看MainActivity的调用,方便二次开发 依赖 compile 'com.nineold ...
- java商品详情页设计_java高并发秒杀系统3-2节商品详情页上.mp4
本Java商城秒杀系统视频教程目录如下: java高并发秒杀系统1-1节java高并发商城秒杀优化学习指引.mp4 java高并发秒杀系统1-2节项目环境搭建(Eclipse)-节.mp4 ja ...
- 【商城开发三】Android 仿淘宝商品详情页下拉足迹修改版
开发商城的快有半个月了,需要做到详情页下拉足迹的效果,网上找了找没找到,找到一个差不多还有点问题,然后在基础上进行了二次开发 感谢http://blog.csdn.net/yaphetzhao/art ...
- iOS 仿淘宝,上拉进入详情页面
今天做的主要是一个模仿淘宝,上拉进入商品详情的功能,主要是通过 tableView 与 webView 一起来实现的,当然也可根据自己的需要把 webView 替换成你想要的 // // ViewCo ...
- 微信小程序之网易云音乐(五)- 排行详情页、歌单详情页、播放器组件开发
微信小程序之网易云音乐(五)- 排行详情页.歌单详情页.播放器组件开发 一. 排行详情页模块 二. 歌单详情页模块 三. 播放器组件 微信小程序之网易云音乐导航 一. 排行详情页模块 rank.vue ...
- 2020 年 GitHub 上那些优秀 Android 开源库,这里是 Top10! | 原力计划
作者 | 依然饭特稀西 责编 | 郭芮 出品 | CSDN博客 每过一段时间呀,我都会给大家带来一些从Github上收集的一些开源库,有的是炫酷动效,有的则是实用的工具和类库.2020年有哪些优秀的开 ...
最新文章
- 【SVN】在阿里云上创建svn服务器
- Android笔记之FragmentTabHost实现选项卡
- 利用vue进行页面滚动监听,上拉刷新
- 安装server 2012 时提示输入的密码不满足网络或组管理员设置的密码复杂度
- Inception代码解读
- 乐视手机android流量,乐视手机流量不能用怎么办
- div中字垂直居中对齐
- AE开发 创建Feature后,需要进行拓扑检查
- Maven学习五之Nexus中各repository介绍
- 计算机专业论文选题的8个方法
- 执念斩长河21年Q2生活心得
- 银河证券的系统也错的太厉害了吧..
- springboot昆明学院档案管理系统毕业设计源码311758
- 浅谈游戏《Cuphead茶杯头》
- 工业互联网二级节点总体架构
- mysql 安装 rpm fc24_mysql 安装
- 晶体谐振器 晶体振荡器 正确区分
- 【转】关于linux中wps出现系统字体缺失的解决方法
- 抖音直播短视频运营带货创业项目营销策划方案计划书
- 周测3 T1 无碳小车