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:
parent
e741ff8aa1
commit
4af4da9089
|
@ -27,10 +27,11 @@ import android.widget.OverScroller;
|
||||||
|
|
||||||
import com.facebook.infer.annotation.Assertions;
|
import com.facebook.infer.annotation.Assertions;
|
||||||
import com.facebook.react.common.ReactConstants;
|
import com.facebook.react.common.ReactConstants;
|
||||||
|
import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||||
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
||||||
import com.facebook.react.uimanager.ReactClippingViewGroup;
|
import com.facebook.react.uimanager.ReactClippingViewGroup;
|
||||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
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 com.facebook.react.views.view.ReactViewBackgroundManager;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
@ -55,6 +56,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
|
||||||
|
|
||||||
private boolean mActivelyScrolling;
|
private boolean mActivelyScrolling;
|
||||||
private @Nullable Rect mClippingRect;
|
private @Nullable Rect mClippingRect;
|
||||||
|
private @Nullable String mOverflow = ViewProps.HIDDEN;
|
||||||
private boolean mDragging;
|
private boolean mDragging;
|
||||||
private boolean mPagingEnabled = false;
|
private boolean mPagingEnabled = false;
|
||||||
private @Nullable Runnable mPostTouchRunnable;
|
private @Nullable Runnable mPostTouchRunnable;
|
||||||
|
@ -181,10 +183,23 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
|
||||||
awakenScrollBars();
|
awakenScrollBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOverflow(String overflow) {
|
||||||
|
mOverflow = overflow;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
getDrawingRect(mRect);
|
getDrawingRect(mRect);
|
||||||
canvas.clipRect(mRect);
|
|
||||||
|
switch (mOverflow) {
|
||||||
|
case ViewProps.VISIBLE:
|
||||||
|
break;
|
||||||
|
case ViewProps.HIDDEN:
|
||||||
|
canvas.clipRect(mRect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,4 +250,9 @@ public class ReactHorizontalScrollViewManager
|
||||||
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24);
|
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24);
|
||||||
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
|
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "overflow")
|
||||||
|
public void setOverflow(ReactHorizontalScrollView view, @Nullable String overflow) {
|
||||||
|
view.setOverflow(overflow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,11 @@ import android.widget.ScrollView;
|
||||||
import com.facebook.infer.annotation.Assertions;
|
import com.facebook.infer.annotation.Assertions;
|
||||||
import com.facebook.react.bridge.ReactContext;
|
import com.facebook.react.bridge.ReactContext;
|
||||||
import com.facebook.react.common.ReactConstants;
|
import com.facebook.react.common.ReactConstants;
|
||||||
|
import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||||
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
import com.facebook.react.uimanager.MeasureSpecAssertions;
|
||||||
import com.facebook.react.uimanager.ReactClippingViewGroup;
|
import com.facebook.react.uimanager.ReactClippingViewGroup;
|
||||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
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 com.facebook.react.views.view.ReactViewBackgroundManager;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
@ -54,6 +55,7 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
|
||||||
|
|
||||||
private boolean mActivelyScrolling;
|
private boolean mActivelyScrolling;
|
||||||
private @Nullable Rect mClippingRect;
|
private @Nullable Rect mClippingRect;
|
||||||
|
private @Nullable String mOverflow = ViewProps.HIDDEN;
|
||||||
private boolean mDragging;
|
private boolean mDragging;
|
||||||
private boolean mPagingEnabled = false;
|
private boolean mPagingEnabled = false;
|
||||||
private @Nullable Runnable mPostTouchRunnable;
|
private @Nullable Runnable mPostTouchRunnable;
|
||||||
|
@ -169,6 +171,11 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
|
||||||
awakenScrollBars();
|
awakenScrollBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOverflow(String overflow) {
|
||||||
|
mOverflow = overflow;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
MeasureSpecAssertions.assertExplicitMeasureSpec(widthMeasureSpec, heightMeasureSpec);
|
MeasureSpecAssertions.assertExplicitMeasureSpec(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
@ -373,7 +380,15 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getDrawingRect(mRect);
|
getDrawingRect(mRect);
|
||||||
canvas.clipRect(mRect);
|
|
||||||
|
switch (mOverflow) {
|
||||||
|
case ViewProps.VISIBLE:
|
||||||
|
break;
|
||||||
|
case ViewProps.HIDDEN:
|
||||||
|
canvas.clipRect(mRect);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
super.draw(canvas);
|
super.draw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,11 @@ public class ReactScrollViewManager
|
||||||
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
|
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactProp(name = "overflow")
|
||||||
|
public void setOverflow(ReactScrollView view, @Nullable String overflow) {
|
||||||
|
view.setOverflow(overflow);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scrollToEnd(
|
public void scrollToEnd(
|
||||||
ReactScrollView scrollView,
|
ReactScrollView scrollView,
|
||||||
|
|
Loading…
Reference in New Issue