diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java index f458c0ab0..d16e58de1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java @@ -14,16 +14,63 @@ import android.view.MotionEvent; import com.facebook.react.bridge.ReactContext; import com.facebook.react.uimanager.events.NativeGestureUtil; +import com.facebook.react.uimanager.PixelUtil; /** * Basic extension of {@link SwipeRefreshLayout} with ReactNative-specific functionality. */ public class ReactSwipeRefreshLayout extends SwipeRefreshLayout { + private static final float DEFAULT_CIRCLE_TARGET = 64; + + private boolean mDidLayout = false; + + private boolean mRefreshing = false; + private float mProgressViewOffset = 0; + + public ReactSwipeRefreshLayout(ReactContext reactContext) { super(reactContext); } + @Override + public void setRefreshing(boolean refreshing) { + mRefreshing = refreshing; + + // `setRefreshing` must be called after the initial layout otherwise it + // doesn't work when mounting the component with `refreshing = true`. + // Known Android issue: https://code.google.com/p/android/issues/detail?id=77712 + if (mDidLayout) { + super.setRefreshing(refreshing); + } + } + + public void setProgressViewOffset(float offset) { + mProgressViewOffset = offset; + + // The view must be measured before calling `getProgressCircleDiameter` so + // don't do it before the initial layout. + if (mDidLayout) { + int diameter = getProgressCircleDiameter(); + int start = Math.round(PixelUtil.toPixelFromDIP(offset)) - diameter; + int end = Math.round(PixelUtil.toPixelFromDIP(offset + DEFAULT_CIRCLE_TARGET) - diameter); + setProgressViewOffset(false, start, end); + } + } + + @Override + public void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + + if (!mDidLayout) { + mDidLayout = true; + + // Update values that must be set after initial layout. + setProgressViewOffset(mProgressViewOffset); + setRefreshing(mRefreshing); + } + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (super.onInterceptTouchEvent(ev)) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java index 5db04a1a7..1ae2bacf5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java @@ -20,7 +20,6 @@ import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.common.MapBuilder; import com.facebook.react.common.SystemClock; -import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.ViewGroupManager; @@ -33,8 +32,6 @@ import com.facebook.react.uimanager.annotations.ReactProp; */ public class SwipeRefreshLayoutManager extends ViewGroupManager { - public static final float REFRESH_TRIGGER_DISTANCE = 48; - @Override protected ReactSwipeRefreshLayout createViewInstance(ThemedReactContext reactContext) { return new ReactSwipeRefreshLayout(reactContext); @@ -74,30 +71,13 @@ public class SwipeRefreshLayoutManager extends ViewGroupManager