Skip to content

Commit 42152a3

Browse files
Alexander Kawrykowfacebook-github-bot
Alexander Kawrykow
authored andcommitted
Support removeClippedSubviews for horizontal ScrollViews
Summary: Currently, horizontal `ScrollViews` don't properly support `removeClippedSubviews`. This is because the container view, `ReactHorizontalScrollContainerView` extends from regular `ViewGroup` instead of `ReactViewGroup` so doesn't have all the logic around clipping children. Moreover, the `ReactHorizontalScrollContainerViewManager` doesn't actually support the `removeClippedSubviews` prop This change: - Makes `ReactHorizontalScrollContainerView` extend from `ReactViewGroup` while maintaining the special logic around RTL scrolling - Factors out a common `ReactClippingViewManager` which will be used to bridge all components which extend `ReactViewGroup` and support clipping. It has the logic for adding/removing children and getting child counts while considering clipped subviews - `ReactViewManager` now extends this new `ReactClippingViewManager` - `ReactHorizontalScrollContainerViewManager` also extends `ReactClippingViewManager` Reviewed By: JoshuaGross Differential Revision: D17708630 fbshipit-source-id: d257566ee54ad46f6d62f176a657c596bba96aa4
1 parent 21f1cce commit 42152a3

File tree

4 files changed

+83
-66
lines changed

4 files changed

+83
-66
lines changed

ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
package com.facebook.react.views.scroll;
77

88
import android.content.Context;
9-
import android.view.ViewGroup;
109
import android.widget.HorizontalScrollView;
1110
import androidx.core.view.ViewCompat;
1211
import com.facebook.react.modules.i18nmanager.I18nUtil;
12+
import com.facebook.react.views.view.ReactViewGroup;
1313

1414
/** Container of Horizontal scrollViews that supports RTL scrolling. */
15-
public class ReactHorizontalScrollContainerView extends ViewGroup {
15+
public class ReactHorizontalScrollContainerView extends ReactViewGroup {
1616

1717
private int mLayoutDirection;
1818
private int mCurrentWidth;

ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
import com.facebook.react.module.annotations.ReactModule;
99
import com.facebook.react.uimanager.ThemedReactContext;
10-
import com.facebook.react.uimanager.ViewGroupManager;
10+
import com.facebook.react.views.view.ReactClippingViewManager;
1111

1212
/** View manager for {@link ReactHorizontalScrollContainerView} components. */
1313
@ReactModule(name = ReactHorizontalScrollContainerViewManager.REACT_CLASS)
1414
public class ReactHorizontalScrollContainerViewManager
15-
extends ViewGroupManager<ReactHorizontalScrollContainerView> {
15+
extends ReactClippingViewManager<ReactHorizontalScrollContainerView> {
1616

1717
public static final String REACT_CLASS = "AndroidHorizontalScrollContentView";
1818

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) Facebook, Inc. and its affiliates.
2+
3+
// This source code is licensed under the MIT license found in the
4+
// LICENSE file in the root directory of this source tree.
5+
6+
package com.facebook.react.views.view;
7+
8+
import android.view.View;
9+
import com.facebook.react.uimanager.ViewGroupManager;
10+
import com.facebook.react.uimanager.annotations.ReactProp;
11+
12+
/**
13+
* View manager which handles clipped subviews. Useful for custom views which extends from {@link
14+
* com.facebook.react.views.view.ReactViewGroup}
15+
*/
16+
public abstract class ReactClippingViewManager<T extends ReactViewGroup>
17+
extends ViewGroupManager<T> {
18+
19+
@ReactProp(
20+
name = com.facebook.react.uimanager.ReactClippingViewGroupHelper.PROP_REMOVE_CLIPPED_SUBVIEWS)
21+
public void setRemoveClippedSubviews(T view, boolean removeClippedSubviews) {
22+
view.setRemoveClippedSubviews(removeClippedSubviews);
23+
}
24+
25+
@Override
26+
public void addView(T parent, View child, int index) {
27+
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
28+
if (removeClippedSubviews) {
29+
parent.addViewWithSubviewClippingEnabled(child, index);
30+
} else {
31+
parent.addView(child, index);
32+
}
33+
}
34+
35+
@Override
36+
public int getChildCount(T parent) {
37+
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
38+
if (removeClippedSubviews) {
39+
return parent.getAllChildrenCount();
40+
} else {
41+
return parent.getChildCount();
42+
}
43+
}
44+
45+
@Override
46+
public View getChildAt(T parent, int index) {
47+
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
48+
if (removeClippedSubviews) {
49+
return parent.getChildAtWithSubviewClippingEnabled(index);
50+
} else {
51+
return parent.getChildAt(index);
52+
}
53+
}
54+
55+
@Override
56+
public void removeViewAt(T parent, int index) {
57+
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
58+
if (removeClippedSubviews) {
59+
View child = getChildAt(parent, index);
60+
if (child.getParent() != null) {
61+
parent.removeView(child);
62+
}
63+
parent.removeViewWithSubviewClippingEnabled(child);
64+
} else {
65+
parent.removeViewAt(index);
66+
}
67+
}
68+
69+
@Override
70+
public void removeAllViews(T parent) {
71+
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
72+
if (removeClippedSubviews) {
73+
parent.removeAllViewsWithSubviewClippingEnabled();
74+
} else {
75+
parent.removeAllViews();
76+
}
77+
}
78+
}

ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java

+1-62
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.facebook.react.uimanager.Spacing;
2525
import com.facebook.react.uimanager.ThemedReactContext;
2626
import com.facebook.react.uimanager.UIManagerModule;
27-
import com.facebook.react.uimanager.ViewGroupManager;
2827
import com.facebook.react.uimanager.ViewProps;
2928
import com.facebook.react.uimanager.annotations.ReactProp;
3029
import com.facebook.react.uimanager.annotations.ReactPropGroup;
@@ -35,7 +34,7 @@
3534

3635
/** View manager for AndroidViews (plain React Views). */
3736
@ReactModule(name = ReactViewManager.REACT_CLASS)
38-
public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
37+
public class ReactViewManager extends ReactClippingViewManager<ReactViewGroup> {
3938

4039
@VisibleForTesting public static final String REACT_CLASS = ViewProps.VIEW_CLASS_NAME;
4140

@@ -182,12 +181,6 @@ public void setNativeForeground(ReactViewGroup view, @Nullable ReadableMap fg) {
182181
fg == null ? null : ReactDrawableHelper.createDrawableFromJSDescription(view, fg));
183182
}
184183

185-
@ReactProp(
186-
name = com.facebook.react.uimanager.ReactClippingViewGroupHelper.PROP_REMOVE_CLIPPED_SUBVIEWS)
187-
public void setRemoveClippedSubviews(ReactViewGroup view, boolean removeClippedSubviews) {
188-
view.setRemoveClippedSubviews(removeClippedSubviews);
189-
}
190-
191184
@ReactProp(name = ViewProps.NEEDS_OFFSCREEN_ALPHA_COMPOSITING)
192185
public void setNeedsOffscreenAlphaCompositing(
193186
ReactViewGroup view, boolean needsOffscreenAlphaCompositing) {
@@ -354,58 +347,4 @@ private void handleHotspotUpdate(ReactViewGroup root, @Nullable ReadableArray ar
354347
root.drawableHotspotChanged(x, y);
355348
}
356349
}
357-
358-
@Override
359-
public void addView(ReactViewGroup parent, View child, int index) {
360-
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
361-
if (removeClippedSubviews) {
362-
parent.addViewWithSubviewClippingEnabled(child, index);
363-
} else {
364-
parent.addView(child, index);
365-
}
366-
}
367-
368-
@Override
369-
public int getChildCount(ReactViewGroup parent) {
370-
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
371-
if (removeClippedSubviews) {
372-
return parent.getAllChildrenCount();
373-
} else {
374-
return parent.getChildCount();
375-
}
376-
}
377-
378-
@Override
379-
public View getChildAt(ReactViewGroup parent, int index) {
380-
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
381-
if (removeClippedSubviews) {
382-
return parent.getChildAtWithSubviewClippingEnabled(index);
383-
} else {
384-
return parent.getChildAt(index);
385-
}
386-
}
387-
388-
@Override
389-
public void removeViewAt(ReactViewGroup parent, int index) {
390-
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
391-
if (removeClippedSubviews) {
392-
View child = getChildAt(parent, index);
393-
if (child.getParent() != null) {
394-
parent.removeView(child);
395-
}
396-
parent.removeViewWithSubviewClippingEnabled(child);
397-
} else {
398-
parent.removeViewAt(index);
399-
}
400-
}
401-
402-
@Override
403-
public void removeAllViews(ReactViewGroup parent) {
404-
boolean removeClippedSubviews = parent.getRemoveClippedSubviews();
405-
if (removeClippedSubviews) {
406-
parent.removeAllViewsWithSubviewClippingEnabled();
407-
} else {
408-
parent.removeAllViews();
409-
}
410-
}
411350
}

0 commit comments

Comments
 (0)