• 参考文章http://www.jb51.net/article/91858.htm
  • 核心view 有2个

    • 一个是自定义的ViewGroup
    • 一个是自定义的ScrollView
  • 首先是自定义的ScrollView

public class MyScrollView extends ScrollView {public MyScrollView(Context context) {super(context);}public MyScrollView(Context context, AttributeSet attrs) {super(context, attrs);}public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public void setScrollListener(ScrollListener scrollListener) {this.mScrollListener = scrollListener;}private static String TAG=MyScrollView.class.getName();private ScrollListener mScrollListener;@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()){case MotionEvent.ACTION_MOVE:if(mScrollListener!=null){//得到第一个,也就是子view中]所有的view的 总高点,int contentHeight=getChildAt(0).getHeight();Log.d("---->>>>>" , "contentHeight"+contentHeight);//得到状态栏到屏幕底部的距离,int scrollHeight = getHeight();Log.d("---->>>>>" , "scrollHeight"+scrollHeight);//得到ScrollView中滚动的最高位置int scrollY = getScrollY();Log.d("---->>>>>" , "getScrollY()"+scrollY);mScrollListener.onScroll(scrollY);//判断最高位置+ 状态栏到底部的位置  > 总位置 , 那么就执行到下一个ScrollView的视图,否则还是笨视图if(scrollY+scrollHeight>=contentHeight||contentHeight<=scrollHeight){mScrollListener.onScrollToBottom();}else {mScrollListener.notBottom();}if(scrollY==0){mScrollListener.onScrollToTop();}}break;}boolean result=super.onTouchEvent(ev);//表示子view不能有自己的处理事件requestDisallowInterceptTouchEvent(false);return result;}//滑动监听事件public interface ScrollListener{void onScrollToBottom();//跳到下一页void onScrollToTop();//跳到上一页//根据当前ScrollY是0还是最大来决定跳转还是停留void onScroll(int scrollY);void notBottom();//不跳转}
}
  • 然后就是主要的自定义GroupView
public class MyTwoViewGroup extends ViewGroup {MyScrollView topScrollView, bottomScrollView;VelocityTracker velocityTracker = VelocityTracker.obtain();Scroller scroller = new Scroller(getContext());int currPosition = 0;//0表示第一页,1表示第二页int position1Y;//弹性滑动的Y轴方向int lastY;//记录移动完后最后的坐标public int scaledTouchSlop;//最小滑动距离int speed = 200;//滑动速度boolean isIntercept;//父类是否拦截public boolean bottomScrollVIewIsInTop = false;//true表示第二页已经到最顶部了public boolean topScrollViewIsBottom = false;//true表示第一页已经滚动到最底部了!,public MyTwoViewGroup(Context context) {super(context);init();}public MyTwoViewGroup(Context context, AttributeSet attrs) {super(context, attrs);init();}public MyTwoViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {post(new Runnable() {@Overridepublic void run() {topScrollView = (MyScrollView) getChildAt(0);bottomScrollView = (MyScrollView) getChildAt(1);topScrollView.setScrollListener(new MyScrollView.ScrollListener() {@Overridepublic void onScrollToBottom() {topScrollViewIsBottom = true;}@Overridepublic void onScrollToTop() {}@Overridepublic void onScroll(int scrollY) {}@Overridepublic void notBottom() {topScrollViewIsBottom = false;//底部不显示}});bottomScrollView.setScrollListener(new MyScrollView.ScrollListener() {@Overridepublic void onScrollToBottom() {}@Overridepublic void onScrollToTop() {}@Overridepublic void onScroll(int scrollY) {if (scrollY == 0) {bottomScrollVIewIsInTop = true;} else {bottomScrollVIewIsInTop = false;}}@Overridepublic void notBottom() {}});position1Y = topScrollView.getBottom();scaledTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();}});}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {//防止子View禁止父view拦截事件this.requestDisallowInterceptTouchEvent(false);return super.dispatchTouchEvent(ev);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {int y = (int) ev.getY();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:lastY = y;break;case MotionEvent.ACTION_MOVE://判断是否已经滚动到了底部if (topScrollViewIsBottom) {int dy = lastY - y;//判断是否是向上滑动和是否在第一屏if (dy > 0 && currPosition == 0) {//偏离量是否 大于 滑动速度if (dy >= scaledTouchSlop) {isIntercept = true;//拦截事件lastY=y;}}}if (bottomScrollVIewIsInTop) {int dy = lastY - y;//判断是否是向下滑动和是否在第二屏if (dy < 0 && currPosition == 1) {if (Math.abs(dy) >= scaledTouchSlop) {isIntercept = true;}}}break;}return isIntercept;}@Overridepublic boolean onTouchEvent(MotionEvent event) {int y = (int) event.getY();//添加一个用户的运动跟踪velocityTracker.addMovement(event);switch (event.getAction()) {case MotionEvent.ACTION_MOVE:int dy = lastY - y;if (getScrollY() + dy < 0) {dy = getScrollY() + dy + Math.abs(getScrollY() + dy);}if (getScrollY() + dy + getHeight() > bottomScrollView.getBottom()) {dy = dy - (getScrollY() + dy - (bottomScrollView.getBottom() - getHeight()));}scrollBy(0, dy);break;case MotionEvent.ACTION_UP:isIntercept = false;//计算当前速度的基础上,收集点velocityTracker.computeCurrentVelocity(1000);//检索最后计算Y速度。float yVelocity = velocityTracker.getYVelocity();if (currPosition == 0) {if (yVelocity < 0 && yVelocity < -speed) {smoothScroll(position1Y);currPosition = 1;} else {smoothScroll(0);}} else {if (yVelocity > 0 && yVelocity > speed) {smoothScroll(0);currPosition = 0;} else {smoothScroll(position1Y);}}break;}lastY = y;return true;}//子view的宽高@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);measureChildren(widthMeasureSpec, heightMeasureSpec);}//第一个子view自身高度, 第二个子view的 顶部 是从第一个子view的总高度开始的@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {int childCount = getChildCount();int childTop = t;for (int i = 0; i < childCount; i++) {View child = getChildAt(i);child.layout(l, childTop, r, childTop + child.getMeasuredHeight());childTop += child.getMeasuredHeight();}}//通过Scroller实现弹性滑动private void smoothScroll(int tartY) {int dy = tartY - getScrollY();scroller.startScroll(getScrollX(), getScrollY(), 0, dy);invalidate();//重绘}//onDraw中执行这个@Overridepublic void computeScroll() {if (scroller.computeScrollOffset()) {scrollTo(scroller.getCurrX(), scroller.getCurrY());postInvalidate();}}
}
  • 然后就是布局文件的使用

    • 主要就是2个自定义的ScrollView中放置的子view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.xingao.com.recycleviewtest.DetailActivity"><com.xingao.com.recycleviewtest.ui.MyTwoViewGroupandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.xingao.com.recycleviewtest.ui.MyScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:fillViewport="true"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ImageViewandroid:scaleType="fitXY"android:src="@drawable/a1"android:layout_width="match_parent"android:layout_height="wrap_content" /><TextViewandroid:text="这里是标题"android:textSize="18dp"android:layout_marginRight="10dp"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"android:layout_width="match_parent"android:layout_height="wrap_content" /><TextViewandroid:layout_marginTop="10dp"android:text="子标题"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:textSize="18dp"android:layout_width="match_parent"android:layout_height="wrap_content" /><LinearLayoutandroid:layout_height="0dp"android:layout_weight="1"android:gravity="bottom"android:layout_width="match_parent"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:height="50dp"android:background="#b11"android:gravity="center"android:text="继续拖动查看图文详情"android:textColor="#000" /></LinearLayout></LinearLayout></com.xingao.com.recycleviewtest.ui.MyScrollView><com.xingao.com.recycleviewtest.ui.MyScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:fillViewport="true"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><ImageViewandroid:layout_width="match_parent"android:layout_height="200dp"android:scaleType="fitXY"android:src="@drawable/a1" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/a3" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/a3" /></LinearLayout></com.xingao.com.recycleviewtest.ui.MyScrollView></com.xingao.com.recycleviewtest.ui.MyTwoViewGroup>
</RelativeLayout>
  • -

仿淘宝商品详情页中(继续拖动到图文详情)相关推荐

  1. 仿淘宝商品放大展示效果制作(放大镜效果)

    如果您觉得这篇文章有用,欢迎点赞收藏或有什么建议请在评论区留言,我看到后会第一时间回复的,谢谢! (分享时刻) mac上取色比较好用的小工具:啜色: 好用的截屏小工具:Snipaste (常用的一个功 ...

  2. Android 仿淘宝商品详情页下拉足迹Demo

    DropDownMultiPager 仿淘宝等商品详情页下拉足迹效果SimpleDemo 可colne之后看MainActivity的调用,方便二次开发 依赖 compile 'com.nineold ...

  3. Android开发之仿淘宝商品详情页

    看到有人在问如何实现淘宝商品详情页效果,手痒了就撸了一个,献上效果图 大致梳理一下思路,这里不提供源码 状态栏透明使用开源库StatusBarCompat,为了兼容手机4.4 dependencies ...

  4. 仿淘宝商品浏览界面, 向上拉查看详情

    最新项目中有展示类似淘宝商品详情的功能,主要实现  向上拉查看详情,百度一搜,发现有大神已经实现这个效果了 http://blog.csdn.net/zhongkejingwang/article/d ...

  5. 仿淘宝商品详情-点击显示大图,可滑动

    现在在做一个商城类的项目: 大家都用过淘宝,需求就是要求仿淘宝的效果做一个, 直接上图 用到了一个项目PhotoView 大家运行一下看最后一个项目,把单一的图片显示改成VIewpager就好.

  6. 读淘宝商品描述页源码delphi版

    淘宝的宝贝描述页是ajax异步载入的,所以直接idhttp读一下是弄不到它的源码的.用下面的方法就可以. 代码如下: unit Unit1; interface uses   Windows, Mes ...

  7. 仿淘宝商品界面(html div+css)

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  8. 仿淘宝商品详情页图片滑动并且数字也跟着变化

    今天遇到需求需要做个淘宝那样的商品详情页如图(这里只差放图片了)支持移动端,当然用的是swiper.js支持左右滑动 上代码 html代码 <div class="swiper-con ...

  9. 仿淘宝商品详情页TabLayout+ListView

    第一次写博客,我是一名Android的小码农写代码也有三四年了.有点好玩的跟大家分享一下 项目对商品详情页改版有新需求.顶部是一个渐变的Title包括"宝贝","详情&q ...

最新文章

  1. 1052 Linked List Sorting
  2. 银行程序代发工资的方法
  3. PHP判断上传文件类型
  4. fastai学习:05_pet_breeds Questionnaire
  5. 项目管理--项目整合管理
  6. 智能指针可以放到容器中么_Rust语言入门教程 智能指针篇
  7. virtual box 针对Unable to load R3 module 解决方案
  8. python安装csv出错_python处理csv文件问题解决贴
  9. 190729每日一句
  10. 通过userAgent判断用户浏览器
  11. Java项目:外卖订餐管理系统(java+SSM+JSP+jQuery+Ajax+mysql)
  12. Dagger2 学习
  13. 中文转换成拼音实施方法
  14. 超声波模块工作原理分析及程序
  15. RS485通信--AT_SURF案例No.10
  16. 硬盘的读写速度如何计算
  17. Tensorboard无法显示图片
  18. 模拟幂律分布(附C语言代码)
  19. 部门换届推文文字_我院举行第二届学生代表大会暨学生会换届大会
  20. 详细功能描述及代码带您快速接入百度大脑通用文字识别

热门文章

  1. unity学习笔记-精灵集和精灵动画
  2. 如何在 macOS 12 Monterey 中使用快速笔记
  3. Cesium 2020回顾
  4. 基于飞桨的智能攀塔光缆巡检机器人
  5. eclipse检出svn项目后,该文件夹并没有显示绿色
  6. 保准你看了不会后悔的 Linux 基础命令 [值得收藏]
  7. java从弃坑到web
  8. UML类图画法、举例说明、通俗易懂
  9. 2192-救基友记2
  10. matlab画傅立叶变换后相位谱,对一幅图像进行傅里叶变换后,包含频谱(也叫幅度谱)和相位谱两部分,请问那一部分更重要?...