微信朋友圈上面的图片封面,QQ空间说说上面的图片封面都有下拉反弹的效果,这些都是使用滚动栏实现的。下拉,当松开时候。反弹至原来的位置。下拉时候能看到背景图片。那么这里简介一下这样的效果的实现。

本文源代码下载:点击

1、效果图

这部手机显示的分辨率有限,非常老的手机调试。

2、具有反弹效果BounceScrollView

  1. package com.org.scroll;
  2.  
  3. import android.content.Context;
  4. import android.graphics.Rect;
  5. import android.util.AttributeSet;
  6. import android.view.MotionEvent;
  7. import android.view.View;
  8. import android.view.animation.TranslateAnimation;
  9. import android.widget.ScrollView;
  10.  
  11. /**
  12. * ScrollView反弹效果的实现
  13. */
  14. public class BounceScrollView extends ScrollView {
  15. private View inner;// 孩子View
  16.  
  17. private float y;// 点击时y坐标
  18. // 矩形(这里仅仅是个形式,仅仅是用于推断是否须要动画.)
  19. private Rect normal = new Rect();
  20.  
  21. private boolean isCount = false;// 是否開始计算
  22.  
  23. public BounceScrollView(Context context, AttributeSet attrs) {
  24. super(context, attrs);
  25. }
  26.  
  27. /***
  28. * 依据 XML 生成视图工作完毕.该函数在生成视图的最后调用,在全部子视图加入完之后. 即使子类覆盖了 onFinishInflate
  29. * 方法,也应该调用父类的方法,使该方法得以运行.
  30. */
  31. @Override
  32. protected void onFinishInflate() {
  33. if (getChildCount() > 0) {
  34. inner = getChildAt(0);
  35. }
  36. }
  37.  
  38. /***
  39. * 监听touch
  40. */
  41. @Override
  42. public boolean onTouchEvent(MotionEvent ev) {
  43. if (inner != null) {
  44. commOnTouchEvent(ev);
  45. }
  46.  
  47. return super.onTouchEvent(ev);
  48. }
  49.  
  50. /***
  51. * 触摸事件
  52. *
  53. * @param ev
  54. */
  55. public void commOnTouchEvent(MotionEvent ev) {
  56. int action = ev.getAction();
  57. switch (action) {
  58. case MotionEvent.ACTION_DOWN:
  59. break;
  60. case MotionEvent.ACTION_UP:
  61. // 手指松开.
  62. if (isNeedAnimation()) {
  63. animation();
  64. isCount = false;
  65. }
  66. break;
  67. /***
  68. * 排除出第一次移动计算。由于第一次无法得知y坐标。 在MotionEvent.ACTION_DOWN中获取不到,
  69. * 由于此时是MyScrollView的touch事件传递到到了LIstView的孩子item上面.所以从第二次计算開始.
  70. * 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归0. 之后记录准确了就正常运行.
  71. */
  72. case MotionEvent.ACTION_MOVE:
  73. final float preY = y;// 按下时的y坐标
  74. float nowY = ev.getY();// 时时y坐标
  75. int deltaY = (int) (preY - nowY);// 滑动距离
  76. if (!isCount) {
  77. deltaY = 0; // 在这里要归0.
  78. }
  79.  
  80. y = nowY;
  81. // 当滚动到最上或者最下时就不会再滚动,这时移动布局
  82. if (isNeedMove()) {
  83. // 初始化头部矩形
  84. if (normal.isEmpty()) {
  85. // 保存正常的布局位置
  86. normal.set(inner.getLeft(), inner.getTop(),
  87. inner.getRight(), inner.getBottom());
  88. }
  89. // Log.e("jj", "矩形:" + inner.getLeft() + "," + inner.getTop()
  90. // + "," + inner.getRight() + "," + inner.getBottom());
  91. // 移动布局
  92. inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2,
  93. inner.getRight(), inner.getBottom() - deltaY / 2);
  94. }
  95. isCount = true;
  96. break;
  97.  
  98. default:
  99. break;
  100. }
  101. }
  102.  
  103. /***
  104. * 回缩动画
  105. */
  106. public void animation() {
  107. // 开启移动动画
  108. TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),
  109. normal.top);
  110. ta.setDuration(200);
  111. inner.startAnimation(ta);
  112. // 设置回到正常的布局位置
  113. inner.layout(normal.left, normal.top, normal.right, normal.bottom);
  114.  
  115. // Log.e("jj", "回归:" + normal.left + "," + normal.top + "," + normal.right
  116. // + "," + normal.bottom);
  117.  
  118. normal.setEmpty();
  119.  
  120. }
  121.  
  122. // 是否须要开启动画
  123. public boolean isNeedAnimation() {
  124. return !normal.isEmpty();
  125. }
  126.  
  127. /***
  128. * 是否须要移动布局 inner.getMeasuredHeight():获取的是控件的总高度
  129. *
  130. * getHeight():获取的是屏幕的高度
  131. *
  132. * @return
  133. */
  134. public boolean isNeedMove() {
  135. int offset = inner.getMeasuredHeight() - getHeight();
  136. int scrollY = getScrollY();
  137. // Log.e("jj", "scrolly=" + scrollY);
  138. // 0是顶部。后面那个是底部
  139. if (scrollY == 0 || scrollY == offset) {
  140. return true;
  141. }
  142. return false;
  143. }
  144.  
  145. }

3、MainActivity

  1. package com.org.activity;
  2.  
  3. import android.os.Bundle;
  4. import android.app.Activity;
  5. import android.view.Menu;
  6. import android.view.Window;
  7.  
  8. public class MainActivity extends Activity {
  9.  
  10. @Override
  11. protected void onCreate(Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. requestWindowFeature(Window.FEATURE_NO_TITLE);
  14. setContentView(R.layout.activity_main);
  15. }
  16.  
  17. @Override
  18. public boolean onCreateOptionsMenu(Menu menu) {
  19. // Inflate the menu; this adds items to the action bar if it is present.
  20. getMenuInflater().inflate(R.menu.activity_main, menu);
  21. return true;
  22. }
  23.  
  24. }

这个没做什么,主要看布局,以及BounceScrollView类。

4、activity_main布局

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >
  6.  
  7. <include layout="@layout/common_title_bg" />
  8.  
  9. <com.org.scroll.BounceScrollView
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content"
  12. android:background="@drawable/coversation_bg"
  13. android:focusable="true"
  14. android:focusableInTouchMode="true" >
  15.  
  16. <LinearLayout
  17. android:layout_width="match_parent"
  18. android:layout_height="match_parent"
  19. android:orientation="vertical"
  20. android:paddingTop="10.0dip" >
  21.  
  22. <RelativeLayout
  23. android:id="@+id/accountSetting"
  24. android:layout_width="fill_parent"
  25. android:layout_height="63.0dip"
  26. android:background="#80ffffff"
  27. android:focusable="true" >
  28.  
  29. <FrameLayout
  30. android:id="@+id/frameLayout1"
  31. android:layout_width="54.0dip"
  32. android:layout_height="54.0dip"
  33. android:layout_centerVertical="true"
  34. android:layout_marginLeft="10.0dip" >
  35.  
  36. <ImageView
  37. android:id="@+id/face"
  38. android:layout_width="50.0dip"
  39. android:layout_height="50.0dip"
  40. android:layout_gravity="center"
  41. android:contentDescription="@null"
  42. android:src="@drawable/h0" />
  43.  
  44. <ImageView
  45. android:id="@+id/statusIcon"
  46. android:layout_width="18.0dip"
  47. android:layout_height="18.0dip"
  48. android:layout_gravity="bottom|right|center"
  49. android:contentDescription="@null" />
  50. </FrameLayout>
  51.  
  52. <ImageView
  53. android:id="@+id/imageView1"
  54. android:layout_width="wrap_content"
  55. android:layout_height="wrap_content"
  56. android:layout_alignParentRight="true"
  57. android:layout_centerVertical="true"
  58. android:layout_marginRight="10.0dip"
  59. android:contentDescription="@null"
  60. android:duplicateParentState="true" />
  61.  
  62. <TextView
  63. android:id="@+id/status"
  64. android:layout_width="wrap_content"
  65. android:layout_height="wrap_content"
  66. android:layout_alignBottom="@+id/nick"
  67. android:layout_marginRight="10.0dip"
  68. android:layout_toLeftOf="@id/imageView1"
  69. android:duplicateParentState="true"
  70. android:text="在线" />
  71.  
  72. <TextView
  73. android:id="@+id/nick"
  74. android:layout_width="wrap_content"
  75. android:layout_height="wrap_content"
  76. android:layout_centerVertical="true"
  77. android:layout_marginLeft="10.0dip"
  78. android:layout_marginRight="69.0dip"
  79. android:layout_toRightOf="@id/frameLayout1"
  80. android:duplicateParentState="true"
  81. android:ellipsize="end"
  82. android:singleLine="true" />
  83. </RelativeLayout>
  84.  
  85. <LinearLayout
  86. android:layout_width="match_parent"
  87. android:layout_height="600dp"
  88. android:layout_marginTop="16.0dip"
  89. android:layout_weight="2.13"
  90. android:background="#ffffffff"
  91. android:orientation="vertical" >
  92.  
  93. <TextView
  94. android:id="@+id/my_profile"
  95. android:layout_width="fill_parent"
  96. android:layout_height="44.0dip"
  97. android:background="#800000ff"
  98. android:clickable="true"
  99. android:gravity="center_vertical"
  100. android:paddingLeft="10.0dip"
  101. android:paddingRight="10.0dip"
  102. android:text="标题一" />
  103.  
  104. <LinearLayout
  105. android:layout_width="fill_parent"
  106. android:layout_height="wrap_content"
  107. android:layout_marginTop="16.0dip"
  108. android:orientation="vertical" >
  109.  
  110. <RelativeLayout
  111. android:id="@+id/set_feedback"
  112. android:layout_width="fill_parent"
  113. android:layout_height="44.0dip"
  114. android:background="#8000ffff"
  115. android:clickable="true"
  116. android:focusable="true" >
  117.  
  118. <TextView
  119. android:layout_width="wrap_content"
  120. android:layout_height="wrap_content"
  121. android:layout_centerVertical="true"
  122. android:layout_marginLeft="12.0dip"
  123. android:duplicateParentState="true"
  124. android:gravity="center_vertical"
  125. android:text="反馈" />
  126. </RelativeLayout>
  127. </LinearLayout>
  128. </LinearLayout>
  129. </LinearLayout>
  130. </com.org.scroll.BounceScrollView>
  131.  
  132. </LinearLayout>

松开向上弹时候,还能够设置一下,详细用的时候再调试设置一下吧!

本文源代码下载:点击

android 滚动栏下拉反弹的效果(相似微信朋友圈)的更多相关文章

  1. Android实现系统下拉栏的消息提示——Notification

    Android实现系统下拉栏的消息提示--Notification 系统默认样式 默认通知(通用) 效果图 按钮 <Button android:layout_width="match ...

  2. Android 第三方开源下拉框:NiceSpinner

    Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框Spinner所提供的设计样式,而改用自定 ...

  3. Android之SwipeRefreshLayout下拉刷新组件

    SwipeRefreshLayout概述 SwipeRefrshLayout是Google官方更新的一个Widget,可以实现下拉刷新的效果.该控件集成自ViewGroup在support-v4兼容包 ...

  4. Android:有关下拉菜单导航的学习(供自己参考)

    Android:有关==下拉菜单导航==的学习 因为先前的学习都没想着记录自己的学习历程,所以该博客才那么迟才开始写. 内容: ==下拉菜单导航== 学习网站:android Spinner控件详解 ...

  5. android 开发-spinner下拉框控件的实现

    Android提供实现下拉框功能的非常实用的控件Spinner. spinner控件需要向xml资源文件中添加spinner标签,如下: <Spinner android:id="@+ ...

  6. Android第三方开源下拉框:NiceSpinner

     Android第三方开源下拉框:NiceSpinner Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Andro ...

  7. UI中经常出现的下拉框下拉自动筛选效果的实现

    小需求是当你在第一个下拉框选择了国家时,会自动更新第二个省份的下拉框,效果如下 两个下拉选择Html如下: <select id="country_select"> & ...

  8. 美团、点评、猫眼App下拉加载效果的源码分享

    今天我准备拿大众点评.美团.猫眼电影三款App的实例来分享一下APICloud下拉加载这个模块的效果. 美团App下拉加载效果   以美团中的下拉酷似动画的萌萌着小人儿效果作为参考,来实现的一个加载模 ...

  9. 谷歌下解决Pop遮罩层无法遮挡滚动栏下问题

    今天用pop的弹出窗体里,出现一个问题,当网页出现滚动栏里,不能遮挡住,解决Pop遮罩层无法遮挡滚动栏下问题. 可通过下载获取改动后的代码----->进入下载

随机推荐

  1. 文字记录而已!!人民币直充/兑换PayPal美金

    人民币直充/兑换PayPal美金 用PAYPAL国际使用外国货币,没有信用卡是不能冲值的,到淘宝买吧,被骗的几率大一些,弄来弄去,PAYPAL被冻结. 今天朋友介绍使用 中美互动网 让它给自己的PAY ...

  2. Android时间戳与字符串相互转换

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public cl ...

  3. ASP.net 环境搭建

    https://www.cnblogs.com/leizhanjun/p/6081928.html

  4. 4. Vue-Resource / axios 异步插件

    安装 cnmp i vue-resource --save (--save 安装到dependencies下) 引用 <script src="node_modules/vue-res ...

  5. 00089_字节输出流OutputStream

    1.字节输出流OutputStream (1)OutputStream此抽象类,是表示输出字节流的所有类的超类.操作的数据都是字节,定义了输出字节流的基本共性功能方法: (2)输出流中定义都是写wri ...

  6. 【hihocoder 1564】同步H公司的终端

    [链接]http://hihocoder.com/problemset/problem/1564 [题意] 在这里写题意 [题解] 如下图 (上图中节点旁边的红色数字为它的权值) 从叶子节点开始考虑. ...

  7. 并发,three

    引言 很久没有跟大家再聊聊并发了,今天LZ闲来无事,跟大家再聊聊并发.由于时间过去的有点久,因此LZ就不按照常理出牌了,只是把自己的理解记录在此,如果各位猿友觉得有所收获,就点个推荐或者留言激励下LZ ...

  8. 【例题 6-11 UVA-297】Quadtrees

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 发现根本不用存节点信息. 遇到了叶子节点且为黑色,就直接覆盖矩阵就好(因为是并集); [代码] #include <bits/ ...

  9. Hypervisor scheduler

    Techniques for configuring a hypervisor scheduler to make use of cache topology of processors and ph ...

  10. ThreadLocal深入理解与内存泄露分析

    ThreadLocal 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本.所以每个线程都能够独立地改变自己的副本.而不会影响其他线程所相应的副本. ...