{"id":13645157,"url":"https://github.com/cnbleu/SlideDetailsLayout","last_synced_at":"2025-04-21T13:31:51.952Z","repository":{"id":67770952,"uuid":"50279846","full_name":"cnbleu/SlideDetailsLayout","owner":"cnbleu","description":"高仿淘宝、京东商品详情页面的上拉加载图文详情功能。","archived":false,"fork":false,"pushed_at":"2017-07-19T01:50:52.000Z","size":110,"stargazers_count":465,"open_issues_count":13,"forks_count":98,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-11-09T18:41:42.014Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.cnbleu.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cnbleu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-01-24T08:53:42.000Z","updated_at":"2024-07-23T07:55:26.000Z","dependencies_parsed_at":"2023-04-03T10:48:19.642Z","dependency_job_id":null,"html_url":"https://github.com/cnbleu/SlideDetailsLayout","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbleu%2FSlideDetailsLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbleu%2FSlideDetailsLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbleu%2FSlideDetailsLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbleu%2FSlideDetailsLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cnbleu","download_url":"https://codeload.github.com/cnbleu/SlideDetailsLayout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250064701,"owners_count":21368952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:02:29.921Z","updated_at":"2025-04-21T13:31:51.660Z","avatar_url":"https://github.com/cnbleu.png","language":"Java","readme":"\u003e高仿淘宝、京东商品详情页面的上拉加载图文详情功能。使用扩展ViewGroup实现，对事件冲突已经做了处理，可嵌套ListView、WebView等自由使用。\n\n##技术特点\n\n1. 完全继承ViewGroup实现的最小功能；\n2. 针对事件冲突、事件消耗进行处理；\n3. 可嵌套ListView、ViewPager、WebView等；\n4. 快速集成。\n\n##代码\n\n先贴代码，见[Github](https://github.com/cnbleu/SlideDetailsLayout)。\n\n##效果图\n\n![](http://7xifbq.com1.z0.glb.clouddn.com/Fp1xaC2l40QBC8OKgHJfPt5qtlLs)\n\n\n##快速使用\n\n与一般的组件使用方式类似，直接在xml中导入即可，需要注意的是，`SlideDetailsLayout`仅获取子节点中的前两个View，其中第一个作为Front，即概略视图；第二个作为Behind，即图文详情页面。\n\n此处仅列出关键代码，详细代码请参见demo。\n\n1. 布局导入\n\n\t文件名称：activity_main.xml\n\n\t\t\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\t\t\u003ccn.bleu.widget.slidedetails.SlideDetailsLayout\n\t\t    android:id=\"@+id/slidedetails\"\n\t\t    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n\t\t    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n\t\t    app:duration=\"500\"\n\t\t    app:percent=\"0.4\"\n\t\t    app:default_panel=\"front\"\n\t\t    android:layout_width=\"match_parent\"\n\t\t    android:layout_height=\"match_parent\"\u003e\n\t\t\n\t\t    \u003cFrameLayout\n\t\t        android:id=\"@+id/slidedetails_front\"\n\t\t        android:layout_width=\"match_parent\"\n\t\t        android:layout_height=\"match_parent\"/\u003e\n\t\t\n\t\t    \u003cWebView\n\t\t        android:id=\"@+id/slidedetails_behind\"\n\t\t        android:layout_width=\"match_parent\"\n\t\t        android:layout_height=\"match_parent\"\n\t\t        android:background=\"#FF0\"/\u003e\n\t\t\n\t\t\u003c/cn.bleu.widget.slidedetails.SlideDetailsLayout\u003e\n\n\t配置信息如下：\n\n\t1. duration：动画时长，默认为300ms；\n\t2. percent：切换的阈值百分比，如0.2表示滑动具体为屏幕高度的20%时切换；\n\t3. default_panel：默认展示的面板，仅接受两个enum值：front、behind。\n\n\tFrameLayout以及WebView可以切换为任何你想要的View类型，当然可能会存在事件冲突，关于事件冲突的解决参考下文。\n\n2. 代码调用：\n\n\t`SlideDetailsLayout`支持代码动态调用smoothOpen()来开启第二个面板，smoothClose来关闭第二个面板，默认情况，面板是关闭状态。\n\n3. 扩展：\n\n\t如果你嵌套的View与`SlideDetailsLayout`有事件冲突，你可以覆写`canChildScrollVertically(direction)`方法来进行拦截处理。direction为负数时表示向下滑动，反之表示向上滑动。\n\n##实现思路\n\n一个最小的功能集应该包含以下三个方面：\n\n1. 包含两个面板，且可以在上下滑动的时候切换；\n2. 嵌套ListView及WebView时可以正常滑动（图文详情部分假设是通过WebView加载H5页面）；\n3. 允许通过代码调用切换面板及切换事件通知。\n\n###上下滑动\n\n1. 通过`onInterceptTouchEvent`进行事件拦截后，在`onTouchEvent`方法中对触摸信息做进一步处理可以实现竖直方向的滑动；\n\n2. 如下图：\n\t![](http://7xifbq.com1.z0.glb.clouddn.com/Fjq_vDJgvi-7nFtRT8mDZRCCREOB)\n\t\n\tFront、Behind面板是收尾相连上下平铺的两个面板，Front面板的高度为Height，`Top`为Front面板的最顶端，也是坐标系中x轴所在的位置，实红线与虚红线之间的部分为屏幕区域。我们要在屏幕区域滑动两个面板只需要改变两个面板在y轴方向的位移（有正负方向）即可。\n\t\n3. 使滑动生效\n\t\n\t我们知道，自定义布局中有非常重要的两个环节`onMeasure`(测量)和`onLayout`(布局)。测量决定了View的所占的大小，布局决定了View所处的位置。实现滑动的关键思路就在这里，我们在`onLayout`方法中根据通过onInterceptTouchEvent、onTouchEvent得到的滑动信息进行计算而得到布局的位置信息，并把这个位置信息设置到子View上面即可实现滑动。\n\n4. 标尺\n\n\t标尺，即：offset，相对于top的位移。Front面板展示时，offset为0，Behind面板展示时，offset为`Height`。此后所有的计算都是相对于该标尺。\n\n###事件冲突处理\n\n假设父View所在的方向为外，子View所在的方向为内，则：事件的拦截方向为从外向内，事件的消耗方向为从内向外。如果当前View不拦截事件的话，有一定机会可以消耗事件；如果当前View拦截事件的话，则子View原则上不能接受后续事件。我们根据具体的需要来拦截事件或者捡漏掉的事件消耗掉，就能处理事件的冲突了（实际上没有这么简单，以后再进行更详细的描述）。\n\n###面板切换及切换事件通知\n\n刚才说到，滑动的标尺是Front相对于Top的移动，且所有的位移计算都是基于该标尺。那我们在切换面板时只需要知道对应的offset值即可。当然，更改完offset值之后不要忘记调用`requestLayout()`方法。\n\n\n\n\n","funding_links":[],"categories":["详情页"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnbleu%2FSlideDetailsLayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcnbleu%2FSlideDetailsLayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnbleu%2FSlideDetailsLayout/lists"}