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


    原文地址:http://blog.csdn.net/a105865708/article/details/17784041

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

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

    效果如图所示:

    主要代码:

      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     }  
  • 相关阅读:
    【BZOJ5302】[HAOI2018]奇怪的背包(动态规划,容斥原理)
    【BZOJ5303】[HAOI2018]反色游戏(Tarjan,线性基)
    【BZOJ5304】[HAOI2018]字串覆盖(后缀数组,主席树,倍增)
    【BZOJ5305】[HAOI2018]苹果树(组合计数)
    【BZOJ5300】[CQOI2018]九连环 (高精度,FFT)
    【BZOJ5292】[BJOI2018]治疗之雨(高斯消元)
    【BZOJ5298】[CQOI2018]交错序列(动态规划,矩阵快速幂)
    【BZOJ5289】[HNOI2018]排列(贪心)
    Codeforces Round #539 Div1 题解
    【BZOJ5288】[HNOI2018]游戏(拓扑排序)
  • 原文地址:https://www.cnblogs.com/liangstudyhome/p/4152226.html
Copyright © 2020-2023  润新知