Android自定义ScrollView实现反弹效果

android的ScrollView控件默认是没有反弹效果的,当滑动到边缘的时候便不能继续滑动。这里通过自定义ScrollView来实现反弹效果。看下面的效果图,红色图片在最左边,android默认ScrollView控件红色图片在最左边的时候是不能向右滚动的。

这里是水平滚动,我们可以通过自定义类继承自HorizontalScrollView类来实现。


  1. publicclassMyScrollViewextendsHorizontalScrollView{
  2. privateViewinner;
  3. privatefloatx;
  4. privateRectnormal=newRect();
  5. @Override
  6. protectedvoidonFinishInflate(){
  7. if(getChildCount()>0){
  8. inner=getChildAt(0);
  9. }
  10. System.out.println("getChildCount():"+getChildCount());
  11. }
  12. publicMyScrollView(Contextcontext,AttributeSetattrs){
  13. super(context,attrs);
  14. }
  15. @Override
  16. publicbooleanonTouchEvent(MotionEventev){
  17. if(inner==null){
  18. returnsuper.onTouchEvent(ev);
  19. }else{
  20. commOnTouchEvent(ev);
  21. }
  22. returnsuper.onTouchEvent(ev);
  23. }
  24. publicvoidcommOnTouchEvent(MotionEventev){
  25. intaction=ev.getAction();
  26. switch(action){
  27. caseMotionEvent.ACTION_DOWN:
  28. x=ev.getX();
  29. break;
  30. caseMotionEvent.ACTION_UP:
  31. if(isNeedAnimation()){
  32. animation();
  33. }
  34. break;
  35. caseMotionEvent.ACTION_MOVE:
  36. finalfloatpreX=x;
  37. floatnowX=ev.getX();
  38. intdeltaX=(int)(preX-nowX);
  39. //滚动
  40. scrollBy(0,deltaX);
  41. x=nowX;
  42. //当滚动到最左或者最右时就不会再滚动,这时移动布局
  43. if(isNeedMove()){
  44. if(normal.isEmpty()){
  45. //保存正常的布局位置
  46. normal.set(inner.getLeft(),inner.getTop(),inner.getRight(),inner.getBottom());
  47. }
  48. //移动布局
  49. inner.layout(inner.getLeft()-deltaX/2,inner.getTop(),inner.getRight()-deltaX/2,inner.getBottom());
  50. }
  51. break;
  52. default:
  53. break;
  54. }
  55. }
  56. //开启动画移动
  57. publicvoidanimation(){
  58. //开启移动动画
  59. TranslateAnimationta=newTranslateAnimation(0,0,inner.getTop(),normal.top);
  60. ta.setDuration(200);
  61. inner.startAnimation(ta);
  62. //设置回到正常的布局位置
  63. inner.layout(normal.left,normal.top,normal.right,normal.bottom);
  64. normal.setEmpty();
  65. }
  66. //是否需要开启动画
  67. publicbooleanisNeedAnimation(){
  68. return!normal.isEmpty();
  69. }
  70. //是否需要移动布局
  71. publicbooleanisNeedMove(){
  72. intoffset=inner.getMeasuredWidth()-getWidth();
  73. intscrollX=getScrollX();
  74. if(scrollX==0||scrollX==offset){
  75. returntrue;
  76. }
  77. returnfalse;
  78. }
  79. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值