转帖请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17761431),请尊重他人的辛勤劳动成果,谢谢!

我之前写了一篇关于美团网,大众点评的购买框效果的文章Android对ScrollView滚动监听,实现美团、大众点评的购买悬浮效果,我自己感觉效果并不是很好,如果快速滑动界面,显示悬浮框的时候会出现一卡的现象,有些朋友说有时候会出现两个布局的情况,特别是对ScrollView滚动的Y值得监听,我还使用了Handler来获取,还有朋友给我介绍了Scrolling Tricks这个东西,我下载试了下,确实美团网,大众点评的购买框用的是这种效果,但是Scrolling Tricks只能在API11以上使用,这个有点小悲剧,然后我做了下修改,并将实现思路分享给大家,实现起来很简单

首先还是要先对ScrollView进行滚动监听,直接在onScrollChanged()方法中就能获取滚动的Y值,之前那篇文章使用了Handler,走弯路了,直接看代码吧

[java] view plain copy
  1. packagecom.example.meituandemo;
  2. importandroid.content.Context;
  3. importandroid.util.AttributeSet;
  4. importandroid.widget.ScrollView;
  5. /**
  6. *@bloghttp://blog.csdn.net/xiaanming
  7. *
  8. *@authorxiaanming
  9. *
  10. */
  11. publicclassMyScrollViewextendsScrollView{
  12. privateOnScrollListeneronScrollListener;
  13. publicMyScrollView(Contextcontext){
  14. this(context,null);
  15. }
  16. publicMyScrollView(Contextcontext,AttributeSetattrs){
  17. this(context,attrs,0);
  18. }
  19. publicMyScrollView(Contextcontext,AttributeSetattrs,intdefStyle){
  20. super(context,attrs,defStyle);
  21. }
  22. /**
  23. *设置滚动接口
  24. *@paramonScrollListener
  25. */
  26. publicvoidsetOnScrollListener(OnScrollListeneronScrollListener){
  27. this.onScrollListener=onScrollListener;
  28. }
  29. @Override
  30. publicintcomputeVerticalScrollRange(){
  31. returnsuper.computeVerticalScrollRange();
  32. }
  33. @Override
  34. protectedvoidonScrollChanged(intl,intt,intoldl,intoldt){
  35. super.onScrollChanged(l,t,oldl,oldt);
  36. if(onScrollListener!=null){
  37. onScrollListener.onScroll(t);
  38. }
  39. }
  40. /**
  41. *
  42. *滚动的回调接口
  43. *
  44. *@authorxiaanming
  45. *
  46. */
  47. publicinterfaceOnScrollListener{
  48. /**
  49. *回调方法,返回MyScrollView滑动的Y方向距离
  50. *@paramscrollY
  51. *、
  52. */
  53. publicvoidonScroll(intscrollY);
  54. }
  55. }

接下来看看主界面的布局文件

[html] view plain copy
  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. android:id="@+id/parent_layout"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical">
  7. <ImageView
  8. android:id="@+id/imageView1"
  9. android:layout_width="match_parent"
  10. android:layout_height="45dip"
  11. android:scaleType="centerCrop"
  12. android:src="@drawable/navigation_bar"/>
  13. <com.example.meituandemo.MyScrollView
  14. android:id="@+id/scrollView"
  15. android:layout_width="fill_parent"
  16. android:layout_height="fill_parent">
  17. <FrameLayout
  18. android:layout_width="match_parent"
  19. android:layout_height="wrap_content">
  20. <LinearLayout
  21. android:layout_width="match_parent"
  22. android:layout_height="wrap_content"
  23. android:orientation="vertical">
  24. <ImageView
  25. android:id="@+id/iamge"
  26. android:layout_width="match_parent"
  27. android:layout_height="wrap_content"
  28. android:background="@drawable/pic"
  29. android:scaleType="centerCrop"/>
  30. <include
  31. android:id="@+id/buy"
  32. layout="@layout/buy_layout"/>
  33. <ImageView
  34. android:layout_width="match_parent"
  35. android:layout_height="wrap_content"
  36. android:background="@drawable/one"
  37. android:scaleType="centerCrop"/>
  38. <ImageView
  39. android:layout_width="match_parent"
  40. android:layout_height="wrap_content"
  41. android:background="@drawable/one"
  42. android:scaleType="centerCrop"/>
  43. <ImageView
  44. android:layout_width="match_parent"
  45. android:layout_height="wrap_content"
  46. android:background="@drawable/one"
  47. android:scaleType="centerCrop"/>
  48. </LinearLayout>
  49. <include
  50. android:id="@+id/top_buy_layout"
  51. layout="@layout/buy_layout"/>
  52. </FrameLayout>
  53. </com.example.meituandemo.MyScrollView>
  54. </LinearLayout>

下面是布局的效果图

从主界面的布局你可以看出,我们在上面放置了一个购买的布局,可能你会想,先让上面的布局隐藏起来,等下面的布局滑动上来就将其显示出来,如果这样子就跟我之前写的那篇文章差不多,效果不是很棒,所以这篇修改版的肯定不是这样子的,我们还是先看主界面的代码吧

[java] view plain copy
  1. packagecom.example.meituandemo;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.view.ViewTreeObserver.OnGlobalLayoutListener;
  5. importandroid.widget.LinearLayout;
  6. importcom.example.meituandemo.MyScrollView.OnScrollListener;
  7. /**
  8. *@bloghttp://blog.csdn.net/xiaanming
  9. *
  10. *@authorxiaanming
  11. *
  12. */
  13. publicclassMainActivityextendsActivityimplementsOnScrollListener{
  14. /**
  15. *自定义的MyScrollView
  16. */
  17. privateMyScrollViewmyScrollView;
  18. /**
  19. *在MyScrollView里面的购买布局
  20. */
  21. privateLinearLayoutmBuyLayout;
  22. /**
  23. *位于顶部的购买布局
  24. */
  25. privateLinearLayoutmTopBuyLayout;
  26. @SuppressWarnings("deprecation")
  27. @Override
  28. protectedvoidonCreate(BundlesavedInstanceState){
  29. super.onCreate(savedInstanceState);
  30. setContentView(R.layout.activity_main);
  31. myScrollView=(MyScrollView)findViewById(R.id.scrollView);
  32. mBuyLayout=(LinearLayout)findViewById(R.id.buy);
  33. mTopBuyLayout=(LinearLayout)findViewById(R.id.top_buy_layout);
  34. myScrollView.setOnScrollListener(this);
  35. //当布局的状态或者控件的可见性发生改变回调的接口
  36. findViewById(R.id.parent_layout).getViewTreeObserver().addOnGlobalLayoutListener(newOnGlobalLayoutListener(){
  37. @Override
  38. publicvoidonGlobalLayout(){
  39. //这一步很重要,使得上面的购买布局和下面的购买布局重合
  40. onScroll(myScrollView.getScrollY());
  41. }
  42. });
  43. }
  44. @Override
  45. publicvoidonScroll(intscrollY){
  46. intmBuyLayout2ParentTop=Math.max(scrollY,mBuyLayout.getTop());
  47. mTopBuyLayout.layout(0,mBuyLayout2ParentTop,mTopBuyLayout.getWidth(),mBuyLayout2ParentTop+mTopBuyLayout.getHeight());
  48. }
  49. }

主界面就短短的几行代码,可能看完这些代码你还是没有明白到底是怎么做到的,没关系,我给大家说说,其实我们是让上面的购买布局和下面的购买布局重合起来了,layout()这个方法是确定View的大小和位置的,然后将其绘制出来,里面的四个参数分别是View的四个点的坐标,他的坐标不是相对屏幕的原点,而且相对于他的父布局来说的,
我们在主页面最外层的ViewGroup添加了布局状态改变的监听器,当绘制完了屏幕会回调到方法onGlobalLayout()中,我们在onGlobalLayout()方法中手动调用了下onScroll()方法,刚开始myScrollView.getScrollY()等于0,所以说当scrollY小于mBuyLayout.getTop()的时候,上面的购买布局的上边缘到myScrollView的上边缘的距离等于mBuyLayout.getTop()(即下面布局的上边缘到myScrollView的上边缘)所以刚开始上面的购买布局和下面的购买布局重合了。
当myScrollView向上滚动,而上面购买布局的上边缘始终要和myScrollView的上边缘保持mBuyLayout.getTop()这个距离,所以上面的购买布局也跟着向上滚动,当scrollY大于mBuyLayout.getTop()的时候,表示购买布局上边缘滑动到了导航栏布局,所以此时购买布局的上边缘与myScrollView的上边缘始终要保持scrollY这个距离,所以购买布局才会一直在导航栏下面,就好像粘住了一样,不知道你了解了没有?好了,不过根据这种思路你也可以刚开始使用一个悬浮框来覆盖在下面的购买布局上面,然后onScroll()方法中更新悬浮框的位置,不过悬浮框的x,y不是相对于父布局的,这点要注意下,这样子也能实现效果,不过相对于此,要复杂的多,所以我们遇到类似的功能直接使用这种就行了,简洁明了,好了,你是不迫不及待的想看下效果,那我们接下来就运行下程序吧

运行程序你会发现,无论我们怎么滑动,都不会出现之前那篇文章的那些情况,很流畅吧,这跟美团,大众点评的效果完全一致,好了,修改版的讲解就到这里结束了,有问题的请在下面留言,我会为大家解答的!

项目源码,点击下载

含有多个购买布局的效果,下一个购买布局会将上一个购买布局顶上去,使用方法也很简单,只需要将你需要设置的布局设置Tag为sticky, 如

[html] view plain copy
  1. <FrameLayout
  2. android:layout_width="fill_parent"
  3. android:layout_height="100dip"
  4. android:background="#ff00ffff"
  5. android:tag="sticky">
  6. <Button
  7. android:id="@+id/button"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:text="Button"/>
  11. </FrameLayout>

这样子这个布局滚动到了顶部就会粘在顶部,大家可以下载试试!

推荐大家下载下面的代码

多个购买布局效果源码,点击下载

更多相关文章

  1. Android(安卓)动画之帧动画
  2. Android(安卓)自定义Toast显示多种方式
  3. Android手把手教你实现卡片式瀑布流效果(RecyclerView+CardView,附
  4. Android表格布局之设置边框
  5. GitHub Android(安卓)Librarys Top 100 简介
  6. Android优化之布局优化
  7. Android(安卓)Fragment用法详解(2)--动态添加Fragment
  8. Android应用屏幕适应问题的解决
  9. android列表【android开发记录片】android下实现圆角列表布局控

随机推荐

  1. Win2008 R2 mysql 5.5 zip格式mysql 安装
  2. mysql忘记密码怎么办
  3. mysql 5.7.18 免安装版window配置方法
  4. mysql中coalesce()的使用技巧小结
  5. MySQL 压缩的使用场景和解决方案
  6. Mysql使用kill命令解决死锁问题(杀死某条
  7. mysql中替代null的IFNULL()与COALESCE()
  8. mysql5.7.18安装并修改初始密码的方法
  9. Centos7.3下mysql5.7.18安装并修改初始密
  10. MySQL 5.7 mysql command line client 使