Skip to content

Commit 968aa56

Browse files
andreicoman11facebook-github-bot
authored andcommitted
Add border support to ScrollViews
Reviewed By: AaaChiuuu Differential Revision: D4498409 fbshipit-source-id: e5baca47b647c4fcb37cdad8fad951f6749c65f8
1 parent d8694a2 commit 968aa56

File tree

5 files changed

+211
-1
lines changed

5 files changed

+211
-1
lines changed

ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ android_library(
44
name = 'scroll',
55
srcs = glob(['*.java']),
66
deps = [
7+
YOGA_TARGET,
78
react_native_dep('third-party/android/support/v4:lib-support-v4'),
89
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
910
react_native_dep('third-party/java/jsr-305:jsr-305'),
@@ -19,4 +20,3 @@ android_library(
1920
'PUBLIC',
2021
],
2122
)
22-

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import android.graphics.Rect;
1919
import android.graphics.drawable.ColorDrawable;
2020
import android.graphics.drawable.Drawable;
21+
import android.graphics.drawable.LayerDrawable;
2122
import android.view.MotionEvent;
2223
import android.view.View;
2324
import android.widget.HorizontalScrollView;
@@ -27,6 +28,7 @@
2728
import com.facebook.react.uimanager.events.NativeGestureUtil;
2829
import com.facebook.react.uimanager.ReactClippingViewGroup;
2930
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
31+
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
3032

3133
/**
3234
* Similar to {@link ReactScrollView} but only supports horizontal scrolling.
@@ -48,6 +50,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
4850
private @Nullable String mScrollPerfTag;
4951
private @Nullable Drawable mEndBackground;
5052
private int mEndFillColor = Color.TRANSPARENT;
53+
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
5154

5255
public ReactHorizontalScrollView(Context context) {
5356
this(context, null);
@@ -312,4 +315,50 @@ private void smoothScrollToPage(int velocity) {
312315
}
313316
smoothScrollTo(page * width, getScrollY());
314317
}
318+
319+
@Override
320+
public void setBackgroundColor(int color) {
321+
if (color == Color.TRANSPARENT && mReactBackgroundDrawable == null) {
322+
// don't do anything, no need to allocate ReactBackgroundDrawable for transparent background
323+
} else {
324+
getOrCreateReactViewBackground().setColor(color);
325+
}
326+
}
327+
328+
public void setBorderWidth(int position, float width) {
329+
getOrCreateReactViewBackground().setBorderWidth(position, width);
330+
}
331+
332+
public void setBorderColor(int position, float color, float alpha) {
333+
getOrCreateReactViewBackground().setBorderColor(position, color, alpha);
334+
}
335+
336+
public void setBorderRadius(float borderRadius) {
337+
getOrCreateReactViewBackground().setRadius(borderRadius);
338+
}
339+
340+
public void setBorderRadius(float borderRadius, int position) {
341+
getOrCreateReactViewBackground().setRadius(borderRadius, position);
342+
}
343+
344+
public void setBorderStyle(@Nullable String style) {
345+
getOrCreateReactViewBackground().setBorderStyle(style);
346+
}
347+
348+
private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
349+
if (mReactBackgroundDrawable == null) {
350+
mReactBackgroundDrawable = new ReactViewBackgroundDrawable();
351+
Drawable backgroundDrawable = getBackground();
352+
super.setBackground(null); // required so that drawable callback is cleared before we add the
353+
// drawable back as a part of LayerDrawable
354+
if (backgroundDrawable == null) {
355+
super.setBackground(mReactBackgroundDrawable);
356+
} else {
357+
LayerDrawable layerDrawable =
358+
new LayerDrawable(new Drawable[]{mReactBackgroundDrawable, backgroundDrawable});
359+
super.setBackground(layerDrawable);
360+
}
361+
}
362+
return mReactBackgroundDrawable;
363+
}
315364
}

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616

1717
import com.facebook.react.bridge.ReadableArray;
1818
import com.facebook.react.module.annotations.ReactModule;
19+
import com.facebook.react.uimanager.PixelUtil;
20+
import com.facebook.react.uimanager.Spacing;
21+
import com.facebook.react.uimanager.ViewProps;
1922
import com.facebook.react.uimanager.annotations.ReactProp;
2023
import com.facebook.react.uimanager.ThemedReactContext;
2124
import com.facebook.react.uimanager.ViewGroupManager;
2225
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
26+
import com.facebook.react.uimanager.annotations.ReactPropGroup;
27+
import com.facebook.yoga.YogaConstants;
2328

2429
/**
2530
* View manager for {@link ReactHorizontalScrollView} components.
@@ -34,6 +39,10 @@ public class ReactHorizontalScrollViewManager
3439

3540
protected static final String REACT_CLASS = "AndroidHorizontalScrollView";
3641

42+
private static final int[] SPACING_TYPES = {
43+
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
44+
};
45+
3746
private @Nullable FpsListener mFpsListener = null;
3847

3948
public ReactHorizontalScrollViewManager() {
@@ -150,4 +159,52 @@ public void scrollToEnd(
150159
public void setBottomFillColor(ReactHorizontalScrollView view, int color) {
151160
view.setEndFillColor(color);
152161
}
162+
163+
@ReactPropGroup(names = {
164+
ViewProps.BORDER_RADIUS,
165+
ViewProps.BORDER_TOP_LEFT_RADIUS,
166+
ViewProps.BORDER_TOP_RIGHT_RADIUS,
167+
ViewProps.BORDER_BOTTOM_RIGHT_RADIUS,
168+
ViewProps.BORDER_BOTTOM_LEFT_RADIUS
169+
}, defaultFloat = YogaConstants.UNDEFINED)
170+
public void setBorderRadius(ReactHorizontalScrollView view, int index, float borderRadius) {
171+
if (!YogaConstants.isUndefined(borderRadius)) {
172+
borderRadius = PixelUtil.toPixelFromDIP(borderRadius);
173+
}
174+
175+
if (index == 0) {
176+
view.setBorderRadius(borderRadius);
177+
} else {
178+
view.setBorderRadius(borderRadius, index - 1);
179+
}
180+
}
181+
182+
@ReactProp(name = "borderStyle")
183+
public void setBorderStyle(ReactHorizontalScrollView view, @Nullable String borderStyle) {
184+
view.setBorderStyle(borderStyle);
185+
}
186+
187+
@ReactPropGroup(names = {
188+
ViewProps.BORDER_WIDTH,
189+
ViewProps.BORDER_LEFT_WIDTH,
190+
ViewProps.BORDER_RIGHT_WIDTH,
191+
ViewProps.BORDER_TOP_WIDTH,
192+
ViewProps.BORDER_BOTTOM_WIDTH,
193+
}, defaultFloat = YogaConstants.UNDEFINED)
194+
public void setBorderWidth(ReactHorizontalScrollView view, int index, float width) {
195+
if (!YogaConstants.isUndefined(width)) {
196+
width = PixelUtil.toPixelFromDIP(width);
197+
}
198+
view.setBorderWidth(SPACING_TYPES[index], width);
199+
}
200+
201+
@ReactPropGroup(names = {
202+
"borderColor", "borderLeftColor", "borderRightColor", "borderTopColor", "borderBottomColor"
203+
}, customType = "Color")
204+
public void setBorderColor(ReactHorizontalScrollView view, int index, Integer color) {
205+
float rgbComponent =
206+
color == null ? YogaConstants.UNDEFINED : (float) ((int)color & 0x00FFFFFF);
207+
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24);
208+
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
209+
}
153210
}

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import android.graphics.Rect;
1919
import android.graphics.drawable.ColorDrawable;
2020
import android.graphics.drawable.Drawable;
21+
import android.graphics.drawable.LayerDrawable;
2122
import android.util.Log;
2223
import android.view.MotionEvent;
2324
import android.view.View;
@@ -32,6 +33,7 @@
3233
import com.facebook.react.uimanager.ReactClippingViewGroup;
3334
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
3435
import com.facebook.infer.annotation.Assertions;
36+
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
3537

3638
/**
3739
* A simple subclass of ScrollView that doesn't dispatch measure and layout to its children and has
@@ -60,6 +62,7 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
6062
private @Nullable Drawable mEndBackground;
6163
private int mEndFillColor = Color.TRANSPARENT;
6264
private View mContentView;
65+
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
6366

6467
public ReactScrollView(ReactContext context) {
6568
this(context, null);
@@ -380,4 +383,49 @@ public void onLayoutChange(View v, int left, int top, int right, int bottom, int
380383
scrollTo(getScrollX(), maxScrollY);
381384
}
382385
}
386+
387+
public void setBackgroundColor(int color) {
388+
if (color == Color.TRANSPARENT && mReactBackgroundDrawable == null) {
389+
// don't do anything, no need to allocate ReactBackgroundDrawable for transparent background
390+
} else {
391+
getOrCreateReactViewBackground().setColor(color);
392+
}
393+
}
394+
395+
public void setBorderWidth(int position, float width) {
396+
getOrCreateReactViewBackground().setBorderWidth(position, width);
397+
}
398+
399+
public void setBorderColor(int position, float color, float alpha) {
400+
getOrCreateReactViewBackground().setBorderColor(position, color, alpha);
401+
}
402+
403+
public void setBorderRadius(float borderRadius) {
404+
getOrCreateReactViewBackground().setRadius(borderRadius);
405+
}
406+
407+
public void setBorderRadius(float borderRadius, int position) {
408+
getOrCreateReactViewBackground().setRadius(borderRadius, position);
409+
}
410+
411+
public void setBorderStyle(@Nullable String style) {
412+
getOrCreateReactViewBackground().setBorderStyle(style);
413+
}
414+
415+
private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
416+
if (mReactBackgroundDrawable == null) {
417+
mReactBackgroundDrawable = new ReactViewBackgroundDrawable();
418+
Drawable backgroundDrawable = getBackground();
419+
super.setBackground(null); // required so that drawable callback is cleared before we add the
420+
// drawable back as a part of LayerDrawable
421+
if (backgroundDrawable == null) {
422+
super.setBackground(mReactBackgroundDrawable);
423+
} else {
424+
LayerDrawable layerDrawable =
425+
new LayerDrawable(new Drawable[]{mReactBackgroundDrawable, backgroundDrawable});
426+
super.setBackground(layerDrawable);
427+
}
428+
}
429+
return mReactBackgroundDrawable;
430+
}
383431
}

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@
1919
import com.facebook.react.bridge.ReadableArray;
2020
import com.facebook.react.common.MapBuilder;
2121
import com.facebook.react.module.annotations.ReactModule;
22+
import com.facebook.react.uimanager.PixelUtil;
23+
import com.facebook.react.uimanager.Spacing;
24+
import com.facebook.react.uimanager.ViewProps;
2225
import com.facebook.react.uimanager.annotations.ReactProp;
2326
import com.facebook.react.uimanager.ThemedReactContext;
2427
import com.facebook.react.uimanager.ViewGroupManager;
2528
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
29+
import com.facebook.react.uimanager.annotations.ReactPropGroup;
30+
import com.facebook.yoga.YogaConstants;
2631

2732
/**
2833
* View manager for {@link ReactScrollView} components.
@@ -37,6 +42,10 @@ public class ReactScrollViewManager
3742

3843
protected static final String REACT_CLASS = "RCTScrollView";
3944

45+
private static final int[] SPACING_TYPES = {
46+
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
47+
};
48+
4049
private @Nullable FpsListener mFpsListener = null;
4150

4251
public ReactScrollViewManager() {
@@ -139,6 +148,53 @@ public void scrollTo(
139148
scrollView.scrollTo(data.mDestX, data.mDestY);
140149
}
141150
}
151+
@ReactPropGroup(names = {
152+
ViewProps.BORDER_RADIUS,
153+
ViewProps.BORDER_TOP_LEFT_RADIUS,
154+
ViewProps.BORDER_TOP_RIGHT_RADIUS,
155+
ViewProps.BORDER_BOTTOM_RIGHT_RADIUS,
156+
ViewProps.BORDER_BOTTOM_LEFT_RADIUS
157+
}, defaultFloat = YogaConstants.UNDEFINED)
158+
public void setBorderRadius(ReactScrollView view, int index, float borderRadius) {
159+
if (!YogaConstants.isUndefined(borderRadius)) {
160+
borderRadius = PixelUtil.toPixelFromDIP(borderRadius);
161+
}
162+
163+
if (index == 0) {
164+
view.setBorderRadius(borderRadius);
165+
} else {
166+
view.setBorderRadius(borderRadius, index - 1);
167+
}
168+
}
169+
170+
@ReactProp(name = "borderStyle")
171+
public void setBorderStyle(ReactScrollView view, @Nullable String borderStyle) {
172+
view.setBorderStyle(borderStyle);
173+
}
174+
175+
@ReactPropGroup(names = {
176+
ViewProps.BORDER_WIDTH,
177+
ViewProps.BORDER_LEFT_WIDTH,
178+
ViewProps.BORDER_RIGHT_WIDTH,
179+
ViewProps.BORDER_TOP_WIDTH,
180+
ViewProps.BORDER_BOTTOM_WIDTH,
181+
}, defaultFloat = YogaConstants.UNDEFINED)
182+
public void setBorderWidth(ReactScrollView view, int index, float width) {
183+
if (!YogaConstants.isUndefined(width)) {
184+
width = PixelUtil.toPixelFromDIP(width);
185+
}
186+
view.setBorderWidth(SPACING_TYPES[index], width);
187+
}
188+
189+
@ReactPropGroup(names = {
190+
"borderColor", "borderLeftColor", "borderRightColor", "borderTopColor", "borderBottomColor"
191+
}, customType = "Color")
192+
public void setBorderColor(ReactScrollView view, int index, Integer color) {
193+
float rgbComponent =
194+
color == null ? YogaConstants.UNDEFINED : (float) ((int)color & 0x00FFFFFF);
195+
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24);
196+
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
197+
}
142198

143199
@Override
144200
public void scrollToEnd(

0 commit comments

Comments
 (0)