Android自定義ScrollView實現反彈效果

android的ScrollView控件默認是沒有反彈效果的,當滑動到邊緣的時候便不能繼續滑動。這裏經過自定義ScrollView來實現反彈效果。看下面的效果圖,紅色圖片在最左邊,android默認ScrollView控件紅色圖片在最左邊的時候是不能向右滾動的。android

這裏是水平滾動,咱們能夠經過自定義類繼承自HorizontalScrollView類來實現。
ide

  1. public class MyScrollView extends HorizontalScrollView {
  2. private View inner;
  3. private float x;
  4. private Rect normal = new Rect();
  5. @Override
  6. protected void onFinishInflate() {
  7. if (getChildCount() > 0) {
  8. inner = getChildAt(0);
  9. }
  10. System.out.println("getChildCount():" + getChildCount());
  11. }
  12. public MyScrollView(Context context, AttributeSet attrs) {
  13. super(context, attrs);
  14. }
  15. @Override
  16. public boolean onTouchEvent(MotionEvent ev) {
  17. if (inner == null) {
  18. return super.onTouchEvent(ev);
  19. } else {
  20. commOnTouchEvent(ev);
  21. }
  22. return super.onTouchEvent(ev);
  23. }
  24. public void commOnTouchEvent(MotionEvent ev) {
  25. int action = ev.getAction();
  26. switch (action) {
  27. case MotionEvent.ACTION_DOWN:
  28. x = ev.getX();
  29. break;
  30. case MotionEvent.ACTION_UP:
  31. if (isNeedAnimation()) {
  32. animation();
  33. }
  34. break;
  35. case MotionEvent.ACTION_MOVE:
  36. final float preX = x;
  37. float nowX = ev.getX();
  38. int deltaX = (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. public void animation() {
  58. // 開啓移動動畫
  59. TranslateAnimation ta = new TranslateAnimation(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. public boolean isNeedAnimation() {
  68. return !normal.isEmpty();
  69. }
  70. // 是否須要移動佈局
  71. public boolean isNeedMove() {
  72. int offset = inner.getMeasuredWidth() - getWidth();
  73. int scrollX = getScrollX();
  74. if (scrollX == 0 || scrollX == offset) {
  75. return true;
  76. }
  77. return false;
  78. }
  79. }
相關文章
相關標籤/搜索