react-native-navigation的迁移库

ScrollEventListener.java 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package com.reactnativenavigation.interfaces;
  2. import com.facebook.react.uimanager.events.Event;
  3. import com.facebook.react.uimanager.events.EventDispatcher;
  4. import com.facebook.react.uimanager.events.EventDispatcherListener;
  5. import com.facebook.react.views.scroll.ScrollEvent;
  6. import com.reactnativenavigation.utils.ReflectionUtils;
  7. import com.reactnativenavigation.utils.UiThread;
  8. public class ScrollEventListener implements EventDispatcherListener {
  9. public interface OnScrollListener {
  10. void onScrollUp(float nextTranslation);
  11. void onScrollDown(float nextTranslation);
  12. }
  13. public interface OnDragListener {
  14. void onShow();
  15. void onHide();
  16. }
  17. public interface ScrollAwareView {
  18. int getMeasuredHeight();
  19. float getTranslationY();
  20. }
  21. private ScrollAwareView view;
  22. private OnScrollListener onScrollListener;
  23. private OnDragListener dragListener;
  24. private EventDispatcher eventDispatcher;
  25. private int prevScrollY = -1;
  26. private boolean dragStarted;
  27. public ScrollEventListener(EventDispatcher eventDispatcher) {
  28. this.eventDispatcher = eventDispatcher;
  29. }
  30. public void register(ScrollAwareView scrollAwareView, OnScrollListener scrollListener, OnDragListener dragListener) {
  31. this.view = scrollAwareView;
  32. this.onScrollListener = scrollListener;
  33. this.dragListener = dragListener;
  34. eventDispatcher.addListener(this);
  35. }
  36. public void unregister() {
  37. eventDispatcher.removeListener(this);
  38. }
  39. @Override
  40. public void onEventDispatch(Event event) {
  41. if (event instanceof ScrollEvent) {
  42. handleScrollEvent((ScrollEvent) event);
  43. }
  44. }
  45. private void handleScrollEvent(ScrollEvent event) {
  46. try {
  47. if ("topScroll".equals(event.getEventName())) {
  48. int scrollY = (int) ReflectionUtils.getDeclaredField(event, "mScrollY");
  49. onVerticalScroll(scrollY, prevScrollY);
  50. if (scrollY != prevScrollY) {
  51. prevScrollY = scrollY;
  52. }
  53. } else if ("topScrollBeginDrag".equals(event.getEventName())) {
  54. double velocity = (double) ReflectionUtils.getDeclaredField(event, "mYVelocity");
  55. onDrag(true, velocity);
  56. } else if ("topScrollEndDrag".equals(event.getEventName())) {
  57. double velocity = (double) ReflectionUtils.getDeclaredField(event, "mYVelocity");
  58. onDrag(false, velocity);
  59. }
  60. } catch (Exception e) {
  61. e.printStackTrace();
  62. }
  63. }
  64. private void onVerticalScroll(int scrollY, int oldScrollY) {
  65. if (scrollY < 0) return;
  66. if (!dragStarted) return;
  67. if (view == null) return;
  68. final int scrollDiff = calcScrollDiff(scrollY, oldScrollY, view.getMeasuredHeight());
  69. final float translationY = view.getTranslationY() - scrollDiff;
  70. if (scrollDiff < 0) {
  71. onScrollListener.onScrollDown(translationY);
  72. } else {
  73. onScrollListener.onScrollUp(translationY);
  74. }
  75. }
  76. private int calcScrollDiff(int scrollY, int oldScrollY, int measuredHeight) {
  77. int diff = scrollY - oldScrollY;
  78. if (Math.abs(diff) > measuredHeight) {
  79. diff = (Math.abs(diff) / diff) * measuredHeight;
  80. }
  81. return diff;
  82. }
  83. private void onDrag(boolean started, double velocity) {
  84. dragStarted = started;
  85. UiThread.post(() -> {
  86. if (!dragStarted) {
  87. if (velocity > 0) {
  88. dragListener.onShow();
  89. } else {
  90. dragListener.onHide();
  91. }
  92. }
  93. });
  94. }
  95. }