mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-17 23:04:40 +08:00
Add border support to ScrollViews
Reviewed By: AaaChiuuu Differential Revision: D4498409 fbshipit-source-id: e5baca47b647c4fcb37cdad8fad951f6749c65f8
This commit is contained in:
committed by
Facebook Github Bot
parent
d8694a258f
commit
968aa56ca3
@@ -4,6 +4,7 @@ android_library(
|
||||
name = 'scroll',
|
||||
srcs = glob(['*.java']),
|
||||
deps = [
|
||||
YOGA_TARGET,
|
||||
react_native_dep('third-party/android/support/v4:lib-support-v4'),
|
||||
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
|
||||
react_native_dep('third-party/java/jsr-305:jsr-305'),
|
||||
@@ -19,4 +20,3 @@ android_library(
|
||||
'PUBLIC',
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.HorizontalScrollView;
|
||||
@@ -27,6 +28,7 @@ import com.facebook.react.uimanager.MeasureSpecAssertions;
|
||||
import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroup;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
||||
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
|
||||
|
||||
/**
|
||||
* Similar to {@link ReactScrollView} but only supports horizontal scrolling.
|
||||
@@ -48,6 +50,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
|
||||
private @Nullable String mScrollPerfTag;
|
||||
private @Nullable Drawable mEndBackground;
|
||||
private int mEndFillColor = Color.TRANSPARENT;
|
||||
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
|
||||
|
||||
public ReactHorizontalScrollView(Context context) {
|
||||
this(context, null);
|
||||
@@ -312,4 +315,50 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
|
||||
}
|
||||
smoothScrollTo(page * width, getScrollY());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundColor(int color) {
|
||||
if (color == Color.TRANSPARENT && mReactBackgroundDrawable == null) {
|
||||
// don't do anything, no need to allocate ReactBackgroundDrawable for transparent background
|
||||
} else {
|
||||
getOrCreateReactViewBackground().setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBorderWidth(int position, float width) {
|
||||
getOrCreateReactViewBackground().setBorderWidth(position, width);
|
||||
}
|
||||
|
||||
public void setBorderColor(int position, float color, float alpha) {
|
||||
getOrCreateReactViewBackground().setBorderColor(position, color, alpha);
|
||||
}
|
||||
|
||||
public void setBorderRadius(float borderRadius) {
|
||||
getOrCreateReactViewBackground().setRadius(borderRadius);
|
||||
}
|
||||
|
||||
public void setBorderRadius(float borderRadius, int position) {
|
||||
getOrCreateReactViewBackground().setRadius(borderRadius, position);
|
||||
}
|
||||
|
||||
public void setBorderStyle(@Nullable String style) {
|
||||
getOrCreateReactViewBackground().setBorderStyle(style);
|
||||
}
|
||||
|
||||
private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
|
||||
if (mReactBackgroundDrawable == null) {
|
||||
mReactBackgroundDrawable = new ReactViewBackgroundDrawable();
|
||||
Drawable backgroundDrawable = getBackground();
|
||||
super.setBackground(null); // required so that drawable callback is cleared before we add the
|
||||
// drawable back as a part of LayerDrawable
|
||||
if (backgroundDrawable == null) {
|
||||
super.setBackground(mReactBackgroundDrawable);
|
||||
} else {
|
||||
LayerDrawable layerDrawable =
|
||||
new LayerDrawable(new Drawable[]{mReactBackgroundDrawable, backgroundDrawable});
|
||||
super.setBackground(layerDrawable);
|
||||
}
|
||||
}
|
||||
return mReactBackgroundDrawable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,15 @@ import android.view.View;
|
||||
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.Spacing;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewGroupManager;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
||||
import com.facebook.react.uimanager.annotations.ReactPropGroup;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
|
||||
/**
|
||||
* View manager for {@link ReactHorizontalScrollView} components.
|
||||
@@ -34,6 +39,10 @@ public class ReactHorizontalScrollViewManager
|
||||
|
||||
protected static final String REACT_CLASS = "AndroidHorizontalScrollView";
|
||||
|
||||
private static final int[] SPACING_TYPES = {
|
||||
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
|
||||
};
|
||||
|
||||
private @Nullable FpsListener mFpsListener = null;
|
||||
|
||||
public ReactHorizontalScrollViewManager() {
|
||||
@@ -150,4 +159,52 @@ public class ReactHorizontalScrollViewManager
|
||||
public void setBottomFillColor(ReactHorizontalScrollView view, int color) {
|
||||
view.setEndFillColor(color);
|
||||
}
|
||||
|
||||
@ReactPropGroup(names = {
|
||||
ViewProps.BORDER_RADIUS,
|
||||
ViewProps.BORDER_TOP_LEFT_RADIUS,
|
||||
ViewProps.BORDER_TOP_RIGHT_RADIUS,
|
||||
ViewProps.BORDER_BOTTOM_RIGHT_RADIUS,
|
||||
ViewProps.BORDER_BOTTOM_LEFT_RADIUS
|
||||
}, defaultFloat = YogaConstants.UNDEFINED)
|
||||
public void setBorderRadius(ReactHorizontalScrollView view, int index, float borderRadius) {
|
||||
if (!YogaConstants.isUndefined(borderRadius)) {
|
||||
borderRadius = PixelUtil.toPixelFromDIP(borderRadius);
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
view.setBorderRadius(borderRadius);
|
||||
} else {
|
||||
view.setBorderRadius(borderRadius, index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "borderStyle")
|
||||
public void setBorderStyle(ReactHorizontalScrollView view, @Nullable String borderStyle) {
|
||||
view.setBorderStyle(borderStyle);
|
||||
}
|
||||
|
||||
@ReactPropGroup(names = {
|
||||
ViewProps.BORDER_WIDTH,
|
||||
ViewProps.BORDER_LEFT_WIDTH,
|
||||
ViewProps.BORDER_RIGHT_WIDTH,
|
||||
ViewProps.BORDER_TOP_WIDTH,
|
||||
ViewProps.BORDER_BOTTOM_WIDTH,
|
||||
}, defaultFloat = YogaConstants.UNDEFINED)
|
||||
public void setBorderWidth(ReactHorizontalScrollView view, int index, float width) {
|
||||
if (!YogaConstants.isUndefined(width)) {
|
||||
width = PixelUtil.toPixelFromDIP(width);
|
||||
}
|
||||
view.setBorderWidth(SPACING_TYPES[index], width);
|
||||
}
|
||||
|
||||
@ReactPropGroup(names = {
|
||||
"borderColor", "borderLeftColor", "borderRightColor", "borderTopColor", "borderBottomColor"
|
||||
}, customType = "Color")
|
||||
public void setBorderColor(ReactHorizontalScrollView view, int index, Integer color) {
|
||||
float rgbComponent =
|
||||
color == null ? YogaConstants.UNDEFINED : (float) ((int)color & 0x00FFFFFF);
|
||||
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24);
|
||||
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -32,6 +33,7 @@ import com.facebook.react.uimanager.events.NativeGestureUtil;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroup;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
|
||||
|
||||
/**
|
||||
* 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
|
||||
private @Nullable Drawable mEndBackground;
|
||||
private int mEndFillColor = Color.TRANSPARENT;
|
||||
private View mContentView;
|
||||
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
|
||||
|
||||
public ReactScrollView(ReactContext context) {
|
||||
this(context, null);
|
||||
@@ -380,4 +383,49 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
|
||||
scrollTo(getScrollX(), maxScrollY);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBackgroundColor(int color) {
|
||||
if (color == Color.TRANSPARENT && mReactBackgroundDrawable == null) {
|
||||
// don't do anything, no need to allocate ReactBackgroundDrawable for transparent background
|
||||
} else {
|
||||
getOrCreateReactViewBackground().setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBorderWidth(int position, float width) {
|
||||
getOrCreateReactViewBackground().setBorderWidth(position, width);
|
||||
}
|
||||
|
||||
public void setBorderColor(int position, float color, float alpha) {
|
||||
getOrCreateReactViewBackground().setBorderColor(position, color, alpha);
|
||||
}
|
||||
|
||||
public void setBorderRadius(float borderRadius) {
|
||||
getOrCreateReactViewBackground().setRadius(borderRadius);
|
||||
}
|
||||
|
||||
public void setBorderRadius(float borderRadius, int position) {
|
||||
getOrCreateReactViewBackground().setRadius(borderRadius, position);
|
||||
}
|
||||
|
||||
public void setBorderStyle(@Nullable String style) {
|
||||
getOrCreateReactViewBackground().setBorderStyle(style);
|
||||
}
|
||||
|
||||
private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
|
||||
if (mReactBackgroundDrawable == null) {
|
||||
mReactBackgroundDrawable = new ReactViewBackgroundDrawable();
|
||||
Drawable backgroundDrawable = getBackground();
|
||||
super.setBackground(null); // required so that drawable callback is cleared before we add the
|
||||
// drawable back as a part of LayerDrawable
|
||||
if (backgroundDrawable == null) {
|
||||
super.setBackground(mReactBackgroundDrawable);
|
||||
} else {
|
||||
LayerDrawable layerDrawable =
|
||||
new LayerDrawable(new Drawable[]{mReactBackgroundDrawable, backgroundDrawable});
|
||||
super.setBackground(layerDrawable);
|
||||
}
|
||||
}
|
||||
return mReactBackgroundDrawable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,15 @@ import android.view.View;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.uimanager.Spacing;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewGroupManager;
|
||||
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
|
||||
import com.facebook.react.uimanager.annotations.ReactPropGroup;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
|
||||
/**
|
||||
* View manager for {@link ReactScrollView} components.
|
||||
@@ -37,6 +42,10 @@ public class ReactScrollViewManager
|
||||
|
||||
protected static final String REACT_CLASS = "RCTScrollView";
|
||||
|
||||
private static final int[] SPACING_TYPES = {
|
||||
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
|
||||
};
|
||||
|
||||
private @Nullable FpsListener mFpsListener = null;
|
||||
|
||||
public ReactScrollViewManager() {
|
||||
@@ -139,6 +148,53 @@ public class ReactScrollViewManager
|
||||
scrollView.scrollTo(data.mDestX, data.mDestY);
|
||||
}
|
||||
}
|
||||
@ReactPropGroup(names = {
|
||||
ViewProps.BORDER_RADIUS,
|
||||
ViewProps.BORDER_TOP_LEFT_RADIUS,
|
||||
ViewProps.BORDER_TOP_RIGHT_RADIUS,
|
||||
ViewProps.BORDER_BOTTOM_RIGHT_RADIUS,
|
||||
ViewProps.BORDER_BOTTOM_LEFT_RADIUS
|
||||
}, defaultFloat = YogaConstants.UNDEFINED)
|
||||
public void setBorderRadius(ReactScrollView view, int index, float borderRadius) {
|
||||
if (!YogaConstants.isUndefined(borderRadius)) {
|
||||
borderRadius = PixelUtil.toPixelFromDIP(borderRadius);
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
view.setBorderRadius(borderRadius);
|
||||
} else {
|
||||
view.setBorderRadius(borderRadius, index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "borderStyle")
|
||||
public void setBorderStyle(ReactScrollView view, @Nullable String borderStyle) {
|
||||
view.setBorderStyle(borderStyle);
|
||||
}
|
||||
|
||||
@ReactPropGroup(names = {
|
||||
ViewProps.BORDER_WIDTH,
|
||||
ViewProps.BORDER_LEFT_WIDTH,
|
||||
ViewProps.BORDER_RIGHT_WIDTH,
|
||||
ViewProps.BORDER_TOP_WIDTH,
|
||||
ViewProps.BORDER_BOTTOM_WIDTH,
|
||||
}, defaultFloat = YogaConstants.UNDEFINED)
|
||||
public void setBorderWidth(ReactScrollView view, int index, float width) {
|
||||
if (!YogaConstants.isUndefined(width)) {
|
||||
width = PixelUtil.toPixelFromDIP(width);
|
||||
}
|
||||
view.setBorderWidth(SPACING_TYPES[index], width);
|
||||
}
|
||||
|
||||
@ReactPropGroup(names = {
|
||||
"borderColor", "borderLeftColor", "borderRightColor", "borderTopColor", "borderBottomColor"
|
||||
}, customType = "Color")
|
||||
public void setBorderColor(ReactScrollView view, int index, Integer color) {
|
||||
float rgbComponent =
|
||||
color == null ? YogaConstants.UNDEFINED : (float) ((int)color & 0x00FFFFFF);
|
||||
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int)color >>> 24);
|
||||
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrollToEnd(
|
||||
|
||||
Reference in New Issue
Block a user