首页 > 代码库 > 【转】Android自定义控件(二)——有弹性的ScrollView

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

实现了当手指滑动到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     }  

 

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