上一次我们试验了有弹性的ScrollView。详情

这一次,我们来试验有弹性的ScrollView。

国际惯例,效果图:

主要代码:

  1. import android.content.Context;
  2. import android.graphics.Rect;
  3. import android.util.AttributeSet;
  4. import android.view.MotionEvent;
  5. import android.view.animation.Animation;
  6. import android.view.animation.Animation.AnimationListener;
  7. import android.view.animation.TranslateAnimation;
  8. import android.widget.AbsListView;
  9. import android.widget.ListView;
  10. /**
  11. * ElasticScrollView有弹性的ListView
  12. */
  13. public class ElasticListView extends ListView {
  14. private float y;
  15. private Rect normal = new Rect();
  16. private boolean animationFinish = true;
  17. public ElasticListView(Context context) {
  18. super(context);
  19. init();
  20. }
  21. public ElasticListView(Context context, AttributeSet attrs) {
  22. super(context, attrs);
  23. init();
  24. }
  25. protected void onScrollChanged(int l, int t, int oldl, int oldt) {
  26. }
  27. boolean overScrolled = false;
  28. private void init() {
  29. setOnScrollListener(new OnScrollListener() {
  30. @Override
  31. public void onScrollStateChanged(AbsListView view, int scrollState) {
  32. }
  33. @Override
  34. public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  35. overScrolled = false;
  36. }
  37. });
  38. }
  39. @Override
  40. protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
  41. overScrolled = true;
  42. }
  43. @Override
  44. public boolean onTouchEvent(MotionEvent ev) {
  45. commOnTouchEvent(ev);
  46. return super.onTouchEvent(ev);
  47. }
  48. public void commOnTouchEvent(MotionEvent ev) {
  49. if (animationFinish) {
  50. int action = ev.getAction();
  51. switch (action) {
  52. case MotionEvent.ACTION_DOWN:
  53. y = ev.getY();
  54. break;
  55. case MotionEvent.ACTION_UP:
  56. y = 0;
  57. if (isNeedAnimation()) {
  58. animation();
  59. }
  60. break;
  61. case MotionEvent.ACTION_MOVE:
  62. final float preY = y == 0 ? ev.getY() : y;
  63. float nowY = ev.getY();
  64. int deltaY = (int) (preY - nowY);
  65. y = nowY;
  66. // 当滚动到最上或者最下时就不会再滚动,这时移动布局
  67. if (isNeedMove(deltaY)) {
  68. if (normal.isEmpty()) {
  69. // 保存正常的布局位置
  70. normal.set(getLeft(), getTop(), getRight(), getBottom());
  71. }
  72. // 移动布局
  73. layout(getLeft(), getTop() - deltaY / 2, getRight(), getBottom() - deltaY / 2);
  74. }
  75. break;
  76. default:
  77. break;
  78. }
  79. }
  80. }
  81. // 开启动画移动
  82. public void animation() {
  83. // 开启移动动画
  84. TranslateAnimation ta = new TranslateAnimation(0, 0, 0, normal.top - getTop());
  85. ta.setDuration(200);
  86. ta.setAnimationListener(new AnimationListener() {
  87. @Override
  88. public void onAnimationStart(Animation animation) {
  89. animationFinish = false;
  90. }
  91. @Override
  92. public void onAnimationRepeat(Animation animation) {
  93. }
  94. @Override
  95. public void onAnimationEnd(Animation animation) {
  96. clearAnimation();
  97. // 设置回到正常的布局位置
  98. layout(normal.left, normal.top, normal.right, normal.bottom);
  99. normal.setEmpty();
  100. animationFinish = true;
  101. }
  102. });
  103. startAnimation(ta);
  104. }
  105. // 是否需要开启动画
  106. public boolean isNeedAnimation() {
  107. return !normal.isEmpty();
  108. }
  109. // 是否需要移动布局
  110. public boolean isNeedMove(float deltaY) {
  111. if (overScrolled && getChildCount() > 0) {
  112. if (getLastVisiblePosition() == getCount() - 1 && deltaY > 0) {
  113. return true;
  114. }
  115. if (getFirstVisiblePosition() == 0 && deltaY < 0) {
  116. return true;
  117. }
  118. }
  119. return false;
  120. }
  121. }

测试代码:

  1. public class MainActivity extends Activity {
  2. ElasticListView listView;
  3. @Override
  4. protected void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.activity_main);
  7. listView = (ElasticListView) findViewById(R.id.listview);
  8. String[] listValues = new String[20];
  9. for (int i=0;i<listValues.length;i++) {
  10. listValues[i] = "TextView" + i;
  11. }
  12. listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listValues));
  13. }
  14. }
    1. public class MainActivity extends Activity {
    2. ElasticListView listView;
    3. @Override
    4. protected void onCreate(Bundle savedInstanceState) {
    5. super.onCreate(savedInstanceState);
    6. setContentView(R.layout.activity_main);
    7. listView = (ElasticListView) findViewById(R.id.listview);
    8. String[] listValues = new String[20];
    9. for (int i=0;i<listValues.length;i++) {
    10. listValues[i] = "TextView" + i;
    11. }
    12. listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listValues));
    13. }
    14. }

Android自定义控件(三)——有弹性的ListView的更多相关文章

  1. 老猪带你玩转android自定义控件二——自定义索引栏listview

    带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...

  2. 玩转android自定义控件二——自定义索引栏listview

    带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样: 今天,我们就从零到一实现这个具有索引栏的listview. 怎么实现这个控件了,我们应当梳理出一个 ...

  3. Android自定义控件三种方式

    1.组合原生控件(继承自ViewGroup.LinearLayout.FrameLayout.RelativeLayout等)   将原生空间做组合,自定义一些事件 2.自己绘制控件(继承自View) ...

  4. android自定义控件(三) 自定义属性

    书接上回 在xml里建立属性,然后java代码里用typedArray获得这些属性,得到属性后,利用属性做一些事.例:得到xml里的color,赋给paint. 1.在res/values/下新建at ...

  5. android自定义控件(三) 增加内容 自定义属性 format详解

    转自 http://www.gisall.com/html/35/160435-5369.html 1. reference:参考某一资源ID. (1)属性定义: <declare-stylea ...

  6. 【转】Android自定义控件(三)——有弹性的ListView

    原文地址:http://blog.csdn.net/a105865708/article/details/17959459 上一次我们试验了有弹性的ScrollView.详情 这一次,我们来试验有弹性 ...

  7. Android自定义控件——有弹性的ListView,ScrollView

    上一次我们试验了有弹性的ScrollView.详情 这一次,我们来试验有弹性的ScrollView. 国际惯例,效果图: 主要代码: [java] view plaincopy import andr ...

  8. Android自定义控件(四)——让每一个Activity UI都具有弹性

    前面我们已经介绍了如何让你的ScrollView,ListView具有弹性, 今天,我们在前面的基础上,做一下适当的修改,让那些既不是ScrollView,也不是ListView的Activity页面 ...

  9. Android自定义控件之自定义组合控件(三)

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

随机推荐

  1. Linux字符设备中的两个重要结构体(file、inode)

    对于Linux系统中,一般字符设备和驱动之间的函数调用关系如下图所示 上图描述了用户空间应用程序通过系统调用来调用程序的过程.一般而言在驱动程序的设计中,会关系 struct file 和 struc ...

  2. chmod

    0表示没有权限,1表示可执行权限,2表示可写权限,4表示可读权限数字与字符对应关系如下:r=4,w=2,x=1若要rwx属性则4+2+1=7若要rw-属性则4+2=6:若要r-x属性则4+1=5命令: ...

  3. Web文件管理:elFinder.Net(支持FTP)

    elFinder 是一个基于 Web 的文件管理器,灵感来自 Mac OS X 的 Finder 程序. elFinder.Net是.Net版本的一个Demo,使用ASP.NET MVC 4集成,可以 ...

  4. Sql Server添加用户

    1.sa用户登陆之后,在安全性中新建登录名 2.添加登录名,下面的默认数据库选择该用户可访问的默认数据库 3.服务器角色中选择public 4.用户映射中选择该用户可访问的数据库,数据库角色一般选择p ...

  5. 设置cas server使用http非安全协议

    目录 1.tomcat添加https安全协议 2.下载cas server端部署到tomcat上 3.CAS服务器深入配置(连接MYSQL) 4.Apache Shiro 集成Cas作为cas cli ...

  6. javascript改变背景/字体颜色(Through the javascript to change the background and font color)

    鼠标移动到.移出DIV时修改DIV的颜色: 1.Change the font and Div background color--function <div style="width ...

  7. spring的定时任务或者说自动任务

    http://kevin19900306.iteye.com/blog/1397744   //这个是别人的博客   引入除spring.jar外的Quartz的jar包quartz-all-1.8. ...

  8. (翻译玩)SQLALchemy backref章节文档

    Linking Relationships with Backref 自从在Object Relational Tutorial中第一次提到backref参数后,许多案例中也用到了backref,那么 ...

  9. C 小写字母编程大写并输出

    main(){ FILE *fp; char str[100],filename[10]; int i=0;if((fp=fopen("test","w"))= ...

  10. SDWebImage使用——一个可管理远程图片加载的类库

    SDWebImage使用——一个可管理远程图片加载的类库     SDWebImage使用——一个可管理远程图片加载的类库 SDWebImage托管在github上.https://github.co ...