diff --git a/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java b/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java index 0214d3db1a..79818315c4 100644 --- a/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java +++ b/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java @@ -43,6 +43,15 @@ public void setProperty(T view, String propName, @Nullable Object value) { case "touchSoundDisabled": mViewManager.setTouchSoundDisabled(view, value == null ? false : (boolean) value); break; + case "borderWidth": + mViewManager.setBorderWidth(view, value == null ? 0f : ((Double) value).floatValue()); + break; + case "borderColor": + mViewManager.setBorderColor(view, ColorPropConverter.getColor(value, view.getContext())); + break; + case "borderStyle": + mViewManager.setBorderStyle(view, value == null ? "solid" : (String) value); + break; default: super.setProperty(view, propName, value); } diff --git a/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java b/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java index 1c5aa129f2..8798d2c721 100644 --- a/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java +++ b/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java @@ -20,4 +20,7 @@ public interface RNGestureHandlerButtonManagerInterface { void setRippleColor(T view, @Nullable Integer value); void setRippleRadius(T view, int value); void setTouchSoundDisabled(T view, boolean value); + void setBorderWidth(T view, float value); + void setBorderColor(T view, @Nullable Integer value); + void setBorderStyle(T view, @Nullable String value); } diff --git a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt index 59533f54bd..a165ffd109 100644 --- a/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +++ b/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt @@ -5,6 +5,9 @@ import android.annotation.TargetApi import android.content.Context import android.content.res.ColorStateList import android.graphics.Color +import android.graphics.DashPathEffect +import android.graphics.Paint +import android.graphics.PathEffect import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable import android.graphics.drawable.PaintDrawable @@ -85,6 +88,21 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R view.borderBottomRightRadius = borderBottomRightRadius } + @ReactProp(name = "borderWidth") + override fun setBorderWidth(view: ButtonViewGroup, borderWidth: Float) { + view.borderWidth = borderWidth + } + + @ReactProp(name = "borderColor") + override fun setBorderColor(view: ButtonViewGroup, borderColor: Int?) { + view.borderColor = borderColor + } + + @ReactProp(name = "borderStyle") + override fun setBorderStyle(view: ButtonViewGroup, borderStyle: String?) { + view.borderStyle = borderStyle + } + @ReactProp(name = "rippleColor") override fun setRippleColor(view: ButtonViewGroup, rippleColor: Int?) { view.rippleColor = rippleColor @@ -151,6 +169,18 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R set(radius) = withBackgroundUpdate { field = radius * resources.displayMetrics.density } + var borderWidth = 0f + set(width) = withBackgroundUpdate { + field = width * resources.displayMetrics.density + } + var borderColor: Int? = null + set(color) = withBackgroundUpdate { + field = color + } + var borderStyle: String? = "solid" + set(style) = withBackgroundUpdate { + field = style + } private val hasBorderRadii: Boolean get() = borderRadius != 0f || @@ -199,6 +229,14 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R .toFloatArray() } + private fun buildBorderStyle(): PathEffect? { + return when (borderStyle) { + "dotted" -> DashPathEffect(floatArrayOf(borderWidth, borderWidth, borderWidth, borderWidth), 0f) + "dashed" -> DashPathEffect(floatArrayOf(borderWidth * 3, borderWidth * 3, borderWidth * 3, borderWidth * 3), 0f) + else -> null + } + } + override fun setBackgroundColor(color: Int) = withBackgroundUpdate { _backgroundColor = color } @@ -250,12 +288,23 @@ class RNGestureHandlerButtonViewManager : ViewGroupManager(), R private fun updateBackgroundColor(backgroundColor: Int, selectable: Drawable?) { val colorDrawable = PaintDrawable(backgroundColor) + val borderDrawable = PaintDrawable(Color.TRANSPARENT) if (hasBorderRadii) { colorDrawable.setCornerRadii(buildBorderRadii()) + borderDrawable.setCornerRadii(buildBorderRadii()) + } + + if (borderWidth > 0f) { + borderDrawable.paint.apply { + style = Paint.Style.STROKE + strokeWidth = borderWidth + color = borderColor ?: Color.BLACK + pathEffect = buildBorderStyle() + } } - val layerDrawable = LayerDrawable(if (selectable != null) arrayOf(colorDrawable, selectable) else arrayOf(colorDrawable)) + val layerDrawable = LayerDrawable(if (selectable != null) arrayOf(colorDrawable, selectable, borderDrawable) else arrayOf(colorDrawable, borderDrawable)) background = layerDrawable } diff --git a/example/src/release_tests/rectButton/index.tsx b/example/src/release_tests/rectButton/index.tsx index 9a5fd2b373..4ab3e934ca 100644 --- a/example/src/release_tests/rectButton/index.tsx +++ b/example/src/release_tests/rectButton/index.tsx @@ -1,72 +1,77 @@ import React from 'react'; -import { StyleSheet, Text, View } from 'react-native'; +import { StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native'; import { RectButton } from 'react-native-gesture-handler'; export default function RectButtonBorders() { return ( -