Android ScrollView support for `overflow: visible`

Summary:
ScrollView always clipping children on Android even when `overflow: visible` was specified.
This change just omits the clipping during draw if `overflow: visible` is passed in.
The default is not changed (from hidden to visible) in case there is a performance impact.
Android now matches iOS in behavior. This helps with issue #21116 and resolves #14416.

Reviewed By: shergin

Differential Revision: D9952096

fbshipit-source-id: 367afe33ee7ff0fdc5aa1074d239883aa289888a
This commit is contained in:
Oleg Lokhvitsky 2018-09-24 10:06:02 -07:00 committed by Facebook Github Bot
parent e741ff8aa1
commit 4af4da9089
4 changed files with 44 additions and 4 deletions

View File

@ -27,10 +27,11 @@ import android.widget.OverScroller;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.events.NativeGestureUtil;
import com.facebook.react.uimanager.MeasureSpecAssertions;
import com.facebook.react.uimanager.ReactClippingViewGroup;
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
import com.facebook.react.uimanager.events.NativeGestureUtil;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.views.view.ReactViewBackgroundManager;
import java.lang.reflect.Field;
@ -55,6 +56,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
private boolean mActivelyScrolling;
private @Nullable Rect mClippingRect;
private @Nullable String mOverflow = ViewProps.HIDDEN;
private boolean mDragging;
private boolean mPagingEnabled = false;
private @Nullable Runnable mPostTouchRunnable;
@ -181,10 +183,23 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
awakenScrollBars();
}
public void setOverflow(String overflow) {
mOverflow = overflow;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
getDrawingRect(mRect);
canvas.clipRect(mRect);
switch (mOverflow) {
case ViewProps.VISIBLE:
break;
case ViewProps.HIDDEN:
canvas.clipRect(mRect);
break;
}
super.onDraw(canvas);
}

View File

@ -250,4 +250,9 @@ public class ReactHorizontalScrollViewManager
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24);
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
}
@ReactProp(name = "overflow")
public void setOverflow(ReactHorizontalScrollView view, @Nullable String overflow) {
view.setOverflow(overflow);
}
}

View File

@ -24,10 +24,11 @@ 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.events.NativeGestureUtil;
import com.facebook.react.uimanager.MeasureSpecAssertions;
import com.facebook.react.uimanager.ReactClippingViewGroup;
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
import com.facebook.react.uimanager.events.NativeGestureUtil;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.views.view.ReactViewBackgroundManager;
import java.lang.reflect.Field;
@ -54,6 +55,7 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
private boolean mActivelyScrolling;
private @Nullable Rect mClippingRect;
private @Nullable String mOverflow = ViewProps.HIDDEN;
private boolean mDragging;
private boolean mPagingEnabled = false;
private @Nullable Runnable mPostTouchRunnable;
@ -169,6 +171,11 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
awakenScrollBars();
}
public void setOverflow(String overflow) {
mOverflow = overflow;
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MeasureSpecAssertions.assertExplicitMeasureSpec(widthMeasureSpec, heightMeasureSpec);
@ -373,7 +380,15 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
}
}
getDrawingRect(mRect);
canvas.clipRect(mRect);
switch (mOverflow) {
case ViewProps.VISIBLE:
break;
case ViewProps.HIDDEN:
canvas.clipRect(mRect);
break;
}
super.draw(canvas);
}

View File

@ -245,6 +245,11 @@ public class ReactScrollViewManager
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
}
@ReactProp(name = "overflow")
public void setOverflow(ReactScrollView view, @Nullable String overflow) {
view.setOverflow(overflow);
}
@Override
public void scrollToEnd(
ReactScrollView scrollView,