Cleanup ReactHorizontalScrollView

Reviewed By: achen1

Differential Revision: D6693605

fbshipit-source-id: e58425b2a5b0bf75ffb41ef3ab6fa7ad46222531
This commit is contained in:
David Vacca 2018-01-18 10:32:18 -08:00 committed by Facebook Github Bot
parent 52ffa5d13e
commit 71ec85f24c
3 changed files with 39 additions and 20 deletions

View File

@ -16,6 +16,7 @@ import android.graphics.Color;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.HorizontalScrollView; import android.widget.HorizontalScrollView;
@ -30,6 +31,7 @@ import javax.annotation.Nullable;
/** /**
* Similar to {@link ReactScrollView} but only supports horizontal scrolling. * Similar to {@link ReactScrollView} but only supports horizontal scrolling.
*/ */
@TargetApi(16)
public class ReactHorizontalScrollView extends HorizontalScrollView implements public class ReactHorizontalScrollView extends HorizontalScrollView implements
ReactClippingViewGroup { ReactClippingViewGroup {
@ -271,7 +273,6 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
* don't get any events from Android about this lifecycle, we do all our detection by creating a * don't get any events from Android about this lifecycle, we do all our detection by creating a
* runnable that checks if we scrolled in the last frame and if so assumes we are still scrolling. * runnable that checks if we scrolled in the last frame and if so assumes we are still scrolling.
*/ */
@TargetApi(16)
private void handlePostTouchScrolling(int velocityX, int velocityY) { private void handlePostTouchScrolling(int velocityX, int velocityY) {
// If we aren't going to do anything (send events or snap to page), we can early out. // If we aren't going to do anything (send events or snap to page), we can early out.
if (!mSendMomentumEvents && !mPagingEnabled && !isScrollPerfLoggingEnabled()) { if (!mSendMomentumEvents && !mPagingEnabled && !isScrollPerfLoggingEnabled()) {
@ -298,14 +299,18 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
if (mActivelyScrolling) { if (mActivelyScrolling) {
// We are still scrolling so we just post to check again a frame later // We are still scrolling so we just post to check again a frame later
mActivelyScrolling = false; mActivelyScrolling = false;
ReactHorizontalScrollView.this.postOnAnimationDelayed(this, ReactScrollViewHelper.MOMENTUM_DELAY); ViewCompat.postOnAnimationDelayed(ReactHorizontalScrollView.this,
this,
ReactScrollViewHelper.MOMENTUM_DELAY);
} else { } else {
if (mPagingEnabled && !mSnappingToPage) { if (mPagingEnabled && !mSnappingToPage) {
// Only if we have pagingEnabled and we have not snapped to the page do we // Only if we have pagingEnabled and we have not snapped to the page do we
// need to continue checking for the scroll. And we cause that scroll by asking for it // need to continue checking for the scroll. And we cause that scroll by asking for it
mSnappingToPage = true; mSnappingToPage = true;
smoothScrollToPage(0); smoothScrollToPage(0);
ReactHorizontalScrollView.this.postOnAnimationDelayed(this, ReactScrollViewHelper.MOMENTUM_DELAY); ViewCompat.postOnAnimationDelayed(ReactHorizontalScrollView.this,
this,
ReactScrollViewHelper.MOMENTUM_DELAY);
} else { } else {
if (mSendMomentumEvents) { if (mSendMomentumEvents) {
ReactScrollViewHelper.emitScrollMomentumEndEvent(ReactHorizontalScrollView.this); ReactScrollViewHelper.emitScrollMomentumEndEvent(ReactHorizontalScrollView.this);
@ -316,7 +321,9 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
} }
} }
}; };
postOnAnimationDelayed(mPostTouchRunnable, ReactScrollViewHelper.MOMENTUM_DELAY); ViewCompat.postOnAnimationDelayed(ReactHorizontalScrollView.this,
mPostTouchRunnable,
ReactScrollViewHelper.MOMENTUM_DELAY);
} }
/** /**

View File

@ -9,6 +9,7 @@
package com.facebook.react.views.scroll; package com.facebook.react.views.scroll;
import android.annotation.TargetApi;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Rect; import android.graphics.Rect;
@ -39,13 +40,14 @@ import javax.annotation.Nullable;
* <p>ReactScrollView only supports vertical scrolling. For horizontal scrolling, * <p>ReactScrollView only supports vertical scrolling. For horizontal scrolling,
* use {@link ReactHorizontalScrollView}. * use {@link ReactHorizontalScrollView}.
*/ */
@TargetApi(11)
public class ReactScrollView extends ScrollView implements ReactClippingViewGroup, ViewGroup.OnHierarchyChangeListener, View.OnLayoutChangeListener { public class ReactScrollView extends ScrollView implements ReactClippingViewGroup, ViewGroup.OnHierarchyChangeListener, View.OnLayoutChangeListener {
private static Field sScrollerField; private static @Nullable Field sScrollerField;
private static boolean sTriedToGetScrollerField = false; private static boolean sTriedToGetScrollerField = false;
private final OnScrollDispatchHelper mOnScrollDispatchHelper = new OnScrollDispatchHelper(); private final OnScrollDispatchHelper mOnScrollDispatchHelper = new OnScrollDispatchHelper();
private final OverScroller mScroller; private final @Nullable OverScroller mScroller;
private final VelocityHelper mVelocityHelper = new VelocityHelper(); private final VelocityHelper mVelocityHelper = new VelocityHelper();
private @Nullable Rect mClippingRect; private @Nullable Rect mClippingRect;
@ -71,6 +73,15 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
mFpsListener = fpsListener; mFpsListener = fpsListener;
mReactBackgroundManager = new ReactViewBackgroundManager(this); mReactBackgroundManager = new ReactViewBackgroundManager(this);
mScroller = getOverScrollerFromParent();
setOnHierarchyChangeListener(this);
setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY);
}
@Nullable
private OverScroller getOverScrollerFromParent() {
OverScroller scroller;
if (!sTriedToGetScrollerField) { if (!sTriedToGetScrollerField) {
sTriedToGetScrollerField = true; sTriedToGetScrollerField = true;
try { try {
@ -86,32 +97,31 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
if (sScrollerField != null) { if (sScrollerField != null) {
try { try {
Object scroller = sScrollerField.get(this); Object scrollerValue = sScrollerField.get(this);
if (scroller instanceof OverScroller) { if (scrollerValue instanceof OverScroller) {
mScroller = (OverScroller) scroller; scroller = (OverScroller) scrollerValue;
} else { } else {
Log.w( Log.w(
ReactConstants.TAG, ReactConstants.TAG,
"Failed to cast mScroller field in ScrollView (probably due to OEM changes to AOSP)! " + "Failed to cast mScroller field in ScrollView (probably due to OEM changes to AOSP)! " +
"This app will exhibit the bounce-back scrolling bug :("); "This app will exhibit the bounce-back scrolling bug :(");
mScroller = null; scroller = null;
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new RuntimeException("Failed to get mScroller from ScrollView!", e); throw new RuntimeException("Failed to get mScroller from ScrollView!", e);
} }
} else { } else {
mScroller = null; scroller = null;
} }
setOnHierarchyChangeListener(this); return scroller;
setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY);
} }
public void setSendMomentumEvents(boolean sendMomentumEvents) { public void setSendMomentumEvents(boolean sendMomentumEvents) {
mSendMomentumEvents = sendMomentumEvents; mSendMomentumEvents = sendMomentumEvents;
} }
public void setScrollPerfTag(String scrollPerfTag) { public void setScrollPerfTag(@Nullable String scrollPerfTag) {
mScrollPerfTag = scrollPerfTag; mScrollPerfTag = scrollPerfTag;
} }

View File

@ -9,6 +9,7 @@
package com.facebook.react.views.scroll; package com.facebook.react.views.scroll;
import android.annotation.TargetApi;
import android.graphics.Color; import android.graphics.Color;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder; import com.facebook.react.common.MapBuilder;
@ -31,6 +32,7 @@ import javax.annotation.Nullable;
* <p>Note that {@link ReactScrollView} and {@link ReactHorizontalScrollView} are exposed to JS * <p>Note that {@link ReactScrollView} and {@link ReactHorizontalScrollView} are exposed to JS
* as a single ScrollView component, configured via the {@code horizontal} boolean property. * as a single ScrollView component, configured via the {@code horizontal} boolean property.
*/ */
@TargetApi(11)
@ReactModule(name = ReactScrollViewManager.REACT_CLASS) @ReactModule(name = ReactScrollViewManager.REACT_CLASS)
public class ReactScrollViewManager public class ReactScrollViewManager
extends ViewGroupManager<ReactScrollView> extends ViewGroupManager<ReactScrollView>
@ -98,7 +100,7 @@ public class ReactScrollViewManager
* @param scrollPerfTag * @param scrollPerfTag
*/ */
@ReactProp(name = "scrollPerfTag") @ReactProp(name = "scrollPerfTag")
public void setScrollPerfTag(ReactScrollView view, String scrollPerfTag) { public void setScrollPerfTag(ReactScrollView view, @Nullable String scrollPerfTag) {
view.setScrollPerfTag(scrollPerfTag); view.setScrollPerfTag(scrollPerfTag);
} }
@ -191,8 +193,8 @@ public class ReactScrollViewManager
}, customType = "Color") }, customType = "Color")
public void setBorderColor(ReactScrollView view, int index, Integer color) { public void setBorderColor(ReactScrollView view, int index, Integer color) {
float rgbComponent = float rgbComponent =
color == null ? YogaConstants.UNDEFINED : (float) ((int)color & 0x00FFFFFF); color == null ? YogaConstants.UNDEFINED : (float) (color & 0x00FFFFFF);
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24); float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) (color >>> 24);
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent); view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
} }
@ -211,12 +213,12 @@ public class ReactScrollViewManager
} }
@Override @Override
public @Nullable Map getExportedCustomDirectEventTypeConstants() { public @Nullable Map<String, Object> getExportedCustomDirectEventTypeConstants() {
return createExportedCustomDirectEventTypeConstants(); return createExportedCustomDirectEventTypeConstants();
} }
public static Map createExportedCustomDirectEventTypeConstants() { public static Map<String, Object> createExportedCustomDirectEventTypeConstants() {
return MapBuilder.builder() return MapBuilder.<String, Object>builder()
.put(ScrollEventType.SCROLL.getJSEventName(), MapBuilder.of("registrationName", "onScroll")) .put(ScrollEventType.SCROLL.getJSEventName(), MapBuilder.of("registrationName", "onScroll"))
.put(ScrollEventType.BEGIN_DRAG.getJSEventName(), MapBuilder.of("registrationName", "onScrollBeginDrag")) .put(ScrollEventType.BEGIN_DRAG.getJSEventName(), MapBuilder.of("registrationName", "onScrollBeginDrag"))
.put(ScrollEventType.END_DRAG.getJSEventName(), MapBuilder.of("registrationName", "onScrollEndDrag")) .put(ScrollEventType.END_DRAG.getJSEventName(), MapBuilder.of("registrationName", "onScrollEndDrag"))