【转】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     }  

 

posted @ 2014-12-08 23:32  perfect亮  阅读(422)  评论(0编辑  收藏  举报