• Android自定义控件(二)——有弹性的ScrollView


    本文在http://gundumw100.iteye.com/blog/1075286的基础上稍作修改

    实现了当手指滑动到ScrollView的顶部、底部时,

    可以继续的向上、向下拉伸。当释放手指的时候,向上、下弹回。

    效果如图所示:

    主要代码:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class ElasticScrollView extends ScrollView {  
    2.     private View inner;  
    3.     private float y;  
    4.     private Rect normal = new Rect();  
    5.     private boolean animationFinish = true;  
    6.   
    7.     public ElasticScrollView(Context context) {  
    8.         super(context);  
    9.     }  
    10.   
    11.     public ElasticScrollView(Context context, AttributeSet attrs) {  
    12.         super(context, attrs);  
    13.     }  
    14.   
    15.     @Override  
    16.     protected void onFinishInflate() {  
    17.         if (getChildCount() > 0) {  
    18.             inner = getChildAt(0);  
    19.         }  
    20.     }  
    21.       
    22.     @Override  
    23.     public boolean onInterceptTouchEvent(MotionEvent ev) {  
    24.         return super.onInterceptTouchEvent(ev);  
    25.     }  
    26.   
    27.     @Override  
    28.     public boolean onTouchEvent(MotionEvent ev) {  
    29.         if (inner == null) {  
    30.             return super.onTouchEvent(ev);  
    31.         } else {  
    32.             commOnTouchEvent(ev);  
    33.         }  
    34.         return super.onTouchEvent(ev);  
    35.     }  
    36.   
    37.     public void commOnTouchEvent(MotionEvent ev) {  
    38.         if (animationFinish) {  
    39.             int action = ev.getAction();  
    40.             switch (action) {  
    41.             case MotionEvent.ACTION_DOWN:  
    42. //              System.out.println("ACTION_DOWN");  
    43.                 y = ev.getY();  
    44.                 super.onTouchEvent(ev);  
    45.                 break;  
    46.             case MotionEvent.ACTION_UP:  
    47. //              System.out.println("ACTION_UP");  
    48.                 y = 0;  
    49.                 if (isNeedAnimation()) {  
    50.                     animation();  
    51.                 }  
    52.                 super.onTouchEvent(ev);  
    53.                 break;  
    54.             case MotionEvent.ACTION_MOVE:  
    55. //              System.out.println("ACTION_MOVE");  
    56.                 final float preY = y == 0 ? ev.getY() : y;  
    57.                 float nowY = ev.getY();  
    58.                 int deltaY = (int) (preY - nowY);  
    59.                 // 滚动  
    60. //              scrollBy(0, deltaY);  
    61.   
    62.                 y = nowY;  
    63.                 // 当滚动到最上或者最下时就不会再滚动,这时移动布局  
    64.                 if (isNeedMove()) {  
    65.                     if (normal.isEmpty()) {  
    66.                         // 保存正常的布局位置  
    67.                         normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());  
    68.                     }  
    69.                     // 移动布局  
    70.                     inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2, inner.getRight(), inner.getBottom() - deltaY / 2);  
    71.                 } else {  
    72.                     super.onTouchEvent(ev);  
    73.                 }  
    74.                 break;  
    75.             default:  
    76.                 break;  
    77.             }  
    78.         }  
    79.     }  
    80.   
    81.     // 开启动画移动  
    82.   
    83.     public void animation() {  
    84.         // 开启移动动画  
    85.         TranslateAnimation ta = new TranslateAnimation(0, 0, 0, normal.top - inner.getTop());  
    86.         ta.setDuration(200);  
    87.         ta.setAnimationListener(new AnimationListener() {  
    88.             @Override  
    89.             public void onAnimationStart(Animation animation) {  
    90.                 animationFinish = false;  
    91.   
    92.             }  
    93.   
    94.             @Override  
    95.             public void onAnimationRepeat(Animation animation) {  
    96.   
    97.             }  
    98.   
    99.             @Override  
    100.             public void onAnimationEnd(Animation animation) {  
    101.                 inner.clearAnimation();  
    102.                 // 设置回到正常的布局位置  
    103.                 inner.layout(normal.left, normal.top, normal.right, normal.bottom);  
    104.                 normal.setEmpty();  
    105.                 animationFinish = true;  
    106.             }  
    107.         });  
    108.         inner.startAnimation(ta);  
    109.     }  
    110.   
    111.     // 是否需要开启动画  
    112.     public boolean isNeedAnimation() {  
    113.         return !normal.isEmpty();  
    114.     }  
    115.   
    116.     // 是否需要移动布局  
    117.     public boolean isNeedMove() {  
    118.         int offset = inner.getMeasuredHeight() - getHeight();  
    119.         int scrollY = getScrollY();  
    120.         if (scrollY == 0 || scrollY == offset) {  
    121.             return true;  
    122.         }  
    123.         return false;  
    124.     }  
    125.   
    126. }  
  • 相关阅读:
    mybatis四大接口之 ParameterHandler
    mybatis四大接口之 Executor
    网络协议
    4、Android UI测试
    3、Android构建仪表测试
    【翻译】Ext JS 6.2 早期访问版本发布
    2、Android构建本地单元测试
    1、Android测试入门
    安卓中的事件分发机制源码解析
    安卓IPC机制之Binder详解
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4126083.html
Copyright © 2020-2023  润新知