SlideDetailsLayout

高仿淘宝、京东商品详情页面的上拉加载图文详情功能。

  • Owner: cnbleu/SlideDetailsLayout
  • Platform:
  • License::
  • Category::
  • Topic:
  • Like:
    0
      Compare:

Github stars Tracking Chart

高仿淘宝、京东商品详情页面的上拉加载图文详情功能。使用扩展ViewGroup实现,对事件冲突已经做了处理,可嵌套ListView、WebView等自由使用。

##技术特点

  1. 完全继承ViewGroup实现的最小功能;
  2. 针对事件冲突、事件消耗进行处理;
  3. 可嵌套ListView、ViewPager、WebView等;
  4. 快速集成。

##代码

先贴代码,见Github

##效果图

##快速使用

与一般的组件使用方式类似,直接在xml中导入即可,需要注意的是,SlideDetailsLayout仅获取子节点中的前两个View,其中第一个作为Front,即概略视图;第二个作为Behind,即图文详情页面。

此处仅列出关键代码,详细代码请参见demo。

  1. 布局导入

    文件名称:activity_main.xml

     <?xml version="1.0" encoding="utf-8"?>
     <cn.bleu.widget.slidedetails.SlideDetailsLayout
         android:id="@+id/slidedetails"
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         app:duration="500"
         app:percent="0.4"
         app:default_panel="front"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
    
         <FrameLayout
             android:id="@+id/slidedetails_front"
             android:layout_width="match_parent"
             android:layout_height="match_parent"/>
    
         <WebView
             android:id="@+id/slidedetails_behind"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:background="#FF0"/>
    
     </cn.bleu.widget.slidedetails.SlideDetailsLayout>
    

    配置信息如下:

    1. duration:动画时长,默认为300ms;
    2. percent:切换的阈值百分比,如0.2表示滑动具体为屏幕高度的20%时切换;
    3. default_panel:默认展示的面板,仅接受两个enum值:front、behind。

    FrameLayout以及WebView可以切换为任何你想要的View类型,当然可能会存在事件冲突,关于事件冲突的解决参考下文。

  2. 代码调用:

    SlideDetailsLayout支持代码动态调用smoothOpen()来开启第二个面板,smoothClose来关闭第二个面板,默认情况,面板是关闭状态。

  3. 扩展:

    如果你嵌套的View与SlideDetailsLayout有事件冲突,你可以覆写canChildScrollVertically(direction)方法来进行拦截处理。direction为负数时表示向下滑动,反之表示向上滑动。

##实现思路

一个最小的功能集应该包含以下三个方面:

  1. 包含两个面板,且可以在上下滑动的时候切换;
  2. 嵌套ListView及WebView时可以正常滑动(图文详情部分假设是通过WebView加载H5页面);
  3. 允许通过代码调用切换面板及切换事件通知。

###上下滑动

  1. 通过onInterceptTouchEvent进行事件拦截后,在onTouchEvent方法中对触摸信息做进一步处理可以实现竖直方向的滑动;

  2. 如下图:

    Front、Behind面板是收尾相连上下平铺的两个面板,Front面板的高度为Height,Top为Front面板的最顶端,也是坐标系中x轴所在的位置,实红线与虚红线之间的部分为屏幕区域。我们要在屏幕区域滑动两个面板只需要改变两个面板在y轴方向的位移(有正负方向)即可。

  3. 使滑动生效

    我们知道,自定义布局中有非常重要的两个环节onMeasure(测量)和onLayout(布局)。测量决定了View的所占的大小,布局决定了View所处的位置。实现滑动的关键思路就在这里,我们在onLayout方法中根据通过onInterceptTouchEvent、onTouchEvent得到的滑动信息进行计算而得到布局的位置信息,并把这个位置信息设置到子View上面即可实现滑动。

  4. 标尺

    标尺,即:offset,相对于top的位移。Front面板展示时,offset为0,Behind面板展示时,offset为Height。此后所有的计算都是相对于该标尺。

###事件冲突处理

假设父View所在的方向为外,子View所在的方向为内,则:事件的拦截方向为从外向内,事件的消耗方向为从内向外。如果当前View不拦截事件的话,有一定机会可以消耗事件;如果当前View拦截事件的话,则子View原则上不能接受后续事件。我们根据具体的需要来拦截事件或者捡漏掉的事件消耗掉,就能处理事件的冲突了(实际上没有这么简单,以后再进行更详细的描述)。

###面板切换及切换事件通知

刚才说到,滑动的标尺是Front相对于Top的移动,且所有的位移计算都是基于该标尺。那我们在切换面板时只需要知道对应的offset值即可。当然,更改完offset值之后不要忘记调用requestLayout()方法。

Main metrics

Overview
Name With Ownercnbleu/SlideDetailsLayout
Primary LanguageJava
Program languageJava (Language Count: 1)
Platform
License:
所有者活动
Created At2016-01-24 08:53:42
Pushed At2017-07-19 01:50:52
Last Commit At2016-01-31 13:31:29
Release Count0
用户参与
Stargazers Count459
Watchers Count14
Fork Count94
Commits Count10
Has Issues Enabled
Issues Count17
Issue Open Count12
Pull Requests Count0
Pull Requests Open Count1
Pull Requests Close Count1
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private