From 2ceed954904e4097f37eb99655808452d3e28997 Mon Sep 17 00:00:00 2001 From: Alan Foster Date: Sun, 27 Aug 2017 22:16:15 -0700 Subject: [PATCH] Support flash scroll indicators for android Summary: There is missing support for flash scroll indicators on Android. This PR adds this functionality. Ensured that the functionality works now within iOS _and_ Android ![flashindicators-ios](https://user-images.githubusercontent.com/1271782/29491236-80ecc062-854c-11e7-9562-bdfe03d505f9.gif) ![flashindicators-android](https://user-images.githubusercontent.com/1271782/29491238-826f321c-854c-11e7-955c-cd425afd05f8.gif) Closes https://github.com/facebook/react-native/pull/15566 Differential Revision: D5686942 Pulled By: shergin fbshipit-source-id: 40c8bfec47d660fe8108253bb9ba9fd16ff0d19c --- Libraries/Components/ScrollResponder.js | 9 ++++---- .../scroll/ReactHorizontalScrollView.java | 10 +++++---- .../ReactHorizontalScrollViewManager.java | 19 ++++++++-------- .../react/views/scroll/ReactScrollView.java | 15 +++++++------ .../scroll/ReactScrollViewCommandHelper.java | 20 +++++++++++------ .../views/scroll/ReactScrollViewManager.java | 22 +++++++++---------- 6 files changed, 53 insertions(+), 42 deletions(-) diff --git a/Libraries/Components/ScrollResponder.js b/Libraries/Components/ScrollResponder.js index 36f71422804243..cb16e9b6e507a2 100644 --- a/Libraries/Components/ScrollResponder.js +++ b/Libraries/Components/ScrollResponder.js @@ -467,12 +467,13 @@ var ScrollResponderMixin = { /** * Displays the scroll indicators momentarily. - * - * @platform ios */ scrollResponderFlashScrollIndicators: function() { - invariant(ScrollViewManager && ScrollViewManager.flashScrollIndicators, 'flashScrollIndicators is not implemented'); - ScrollViewManager.flashScrollIndicators(this.scrollResponderGetScrollableNode()); + UIManager.dispatchViewManagerCommand( + this.scrollResponderGetScrollableNode(), + UIManager.RCTScrollView.Commands.flashScrollIndicators, + [] + ); }, /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index b8f6dfabd5d6a9..3acb61e9c9e407 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -9,8 +9,6 @@ package com.facebook.react.views.scroll; -import javax.annotation.Nullable; - import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; @@ -22,13 +20,13 @@ import android.view.MotionEvent; import android.view.View; import android.widget.HorizontalScrollView; - import com.facebook.infer.annotation.Assertions; import com.facebook.react.uimanager.MeasureSpecAssertions; -import com.facebook.react.uimanager.events.NativeGestureUtil; import com.facebook.react.uimanager.ReactClippingViewGroup; import com.facebook.react.uimanager.ReactClippingViewGroupHelper; +import com.facebook.react.uimanager.events.NativeGestureUtil; import com.facebook.react.views.view.ReactViewBackgroundDrawable; +import javax.annotation.Nullable; /** * Similar to {@link ReactScrollView} but only supports horizontal scrolling. @@ -92,6 +90,10 @@ public void setPagingEnabled(boolean pagingEnabled) { mPagingEnabled = pagingEnabled; } + public void flashScrollIndicators() { + awakenScrollBars(); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { MeasureSpecAssertions.assertExplicitMeasureSpec(widthMeasureSpec, heightMeasureSpec); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java index 24996edcf320e7..9d40757919493c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java @@ -9,22 +9,19 @@ package com.facebook.react.views.scroll; -import javax.annotation.Nullable; - import android.graphics.Color; -import android.view.View; - import com.facebook.react.bridge.ReadableArray; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.uimanager.PixelUtil; +import com.facebook.react.uimanager.ReactClippingViewGroupHelper; import com.facebook.react.uimanager.Spacing; -import com.facebook.react.uimanager.ViewProps; -import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ViewGroupManager; -import com.facebook.react.uimanager.ReactClippingViewGroupHelper; +import com.facebook.react.uimanager.ViewProps; +import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; import com.facebook.yoga.YogaConstants; +import javax.annotation.Nullable; /** * View manager for {@link ReactHorizontalScrollView} components. @@ -124,10 +121,14 @@ public void receiveCommand( ReactScrollViewCommandHelper.receiveCommand(this, scrollView, commandId, args); } + @Override + public void flashScrollIndicators(ReactHorizontalScrollView scrollView) { + scrollView.flashScrollIndicators(); + } + @Override public void scrollTo( - ReactHorizontalScrollView scrollView, - ReactScrollViewCommandHelper.ScrollToCommandData data) { + ReactHorizontalScrollView scrollView, ReactScrollViewCommandHelper.ScrollToCommandData data) { if (data.mAnimated) { scrollView.smoothScrollTo(data.mDestX, data.mDestY); } else { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 1336a63125937c..9d71b94457e616 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -9,10 +9,6 @@ package com.facebook.react.views.scroll; -import javax.annotation.Nullable; - -import java.lang.reflect.Field; - import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; @@ -25,15 +21,16 @@ import android.view.ViewGroup; import android.widget.OverScroller; import android.widget.ScrollView; - +import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.ReactContext; import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.MeasureSpecAssertions; -import com.facebook.react.uimanager.events.NativeGestureUtil; import com.facebook.react.uimanager.ReactClippingViewGroup; import com.facebook.react.uimanager.ReactClippingViewGroupHelper; -import com.facebook.infer.annotation.Assertions; +import com.facebook.react.uimanager.events.NativeGestureUtil; import com.facebook.react.views.view.ReactViewBackgroundDrawable; +import java.lang.reflect.Field; +import javax.annotation.Nullable; /** * A simple subclass of ScrollView that doesn't dispatch measure and layout to its children and has @@ -121,6 +118,10 @@ public void setScrollEnabled(boolean scrollEnabled) { mScrollEnabled = scrollEnabled; } + public void flashScrollIndicators() { + awakenScrollBars(); + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { MeasureSpecAssertions.assertExplicitMeasureSpec(widthMeasureSpec, heightMeasureSpec); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewCommandHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewCommandHelper.java index af97a8bba8e47d..0e2df5918c15d8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewCommandHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewCommandHelper.java @@ -9,14 +9,12 @@ package com.facebook.react.views.scroll; -import javax.annotation.Nullable; - -import java.util.Map; - -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.uimanager.PixelUtil; import com.facebook.infer.annotation.Assertions; +import com.facebook.react.bridge.ReadableArray; import com.facebook.react.common.MapBuilder; +import com.facebook.react.uimanager.PixelUtil; +import java.util.Map; +import javax.annotation.Nullable; /** * Helper for view managers to handle commands like 'scrollTo'. @@ -26,10 +24,12 @@ public class ReactScrollViewCommandHelper { public static final int COMMAND_SCROLL_TO = 1; public static final int COMMAND_SCROLL_TO_END = 2; + public static final int COMMAND_FLASH_SCROLL_INDICATORS = 3; public interface ScrollCommandHandler { void scrollTo(T scrollView, ScrollToCommandData data); void scrollToEnd(T scrollView, ScrollToEndCommandData data); + void flashScrollIndicators(T scrollView); } public static class ScrollToCommandData { @@ -58,7 +58,9 @@ public static Map getCommandsMap() { "scrollTo", COMMAND_SCROLL_TO, "scrollToEnd", - COMMAND_SCROLL_TO_END); + COMMAND_SCROLL_TO_END, + "flashScrollIndicators", + COMMAND_FLASH_SCROLL_INDICATORS); } public static void receiveCommand( @@ -82,6 +84,10 @@ public static void receiveCommand( viewManager.scrollToEnd(scrollView, new ScrollToEndCommandData(animated)); return; } + case COMMAND_FLASH_SCROLL_INDICATORS: + viewManager.flashScrollIndicators(scrollView); + return; + default: throw new IllegalArgumentException(String.format( "Unsupported command %d received by %s.", diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index f110330b5708f0..a7d00cd52da60a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -9,25 +9,21 @@ package com.facebook.react.views.scroll; -import javax.annotation.Nullable; - -import java.util.Map; - import android.graphics.Color; -import android.view.View; - import com.facebook.react.bridge.ReadableArray; import com.facebook.react.common.MapBuilder; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.uimanager.PixelUtil; +import com.facebook.react.uimanager.ReactClippingViewGroupHelper; import com.facebook.react.uimanager.Spacing; -import com.facebook.react.uimanager.ViewProps; -import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ViewGroupManager; -import com.facebook.react.uimanager.ReactClippingViewGroupHelper; +import com.facebook.react.uimanager.ViewProps; +import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; import com.facebook.yoga.YogaConstants; +import java.util.Map; +import javax.annotation.Nullable; /** * View manager for {@link ReactScrollView} components. @@ -138,10 +134,14 @@ public void receiveCommand( ReactScrollViewCommandHelper.receiveCommand(this, scrollView, commandId, args); } + @Override + public void flashScrollIndicators(ReactScrollView scrollView) { + scrollView.flashScrollIndicators(); + } + @Override public void scrollTo( - ReactScrollView scrollView, - ReactScrollViewCommandHelper.ScrollToCommandData data) { + ReactScrollView scrollView, ReactScrollViewCommandHelper.ScrollToCommandData data) { if (data.mAnimated) { scrollView.smoothScrollTo(data.mDestX, data.mDestY); } else {