diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java index 0ff53306..26351c5d 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSlider.java @@ -74,8 +74,12 @@ public class ReactSlider extends AppCompatSeekBar { /** Upper limit based on the SeekBar progress 0..total steps */ private int mUpperLimit; + public ThumbDrawable thumbDrawable; + public ReactSlider(Context context, @Nullable AttributeSet attrs) { super(context, attrs); + thumbDrawable = new ThumbDrawable(getThumb()); + setThumb(thumbDrawable); I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance(); super.setLayoutDirection(sharedI18nUtilInstance.isRTL(context) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR); disableStateListAnimatorIfNeeded(); @@ -307,7 +311,7 @@ public void setThumbImage(final String uri) { setSplitTrack(false); } } else { - setThumb(getThumb()); + setThumb(thumbDrawable); } } } diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java index feb5753b..9a23e353 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManager.java @@ -172,6 +172,21 @@ public void setUpperLimit(ReactSlider view, float value) { ReactSliderManagerImpl.setUpperLimit(view, value); } + @Override + public void setSliderThickness(ReactSlider view, double value) { + ReactSliderManagerImpl.setSliderThickness(view, value); + } + + @Override + public void setSliderCornerRoundness(ReactSlider view, double value) { + ReactSliderManagerImpl.setSliderCornerRoundness(view, value); + } + + @Override + public void setThumbSize(ReactSlider view, double value) { + ReactSliderManagerImpl.setThumbSize(view, value, value); + } + @Override @ReactProp(name = "thumbImage") public void setThumbImage(ReactSlider view, @androidx.annotation.Nullable ReadableMap source) { diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java index dff1f9dd..18939463 100644 --- a/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ReactSliderManagerImpl.java @@ -1,11 +1,14 @@ package com.reactnativecommunity.slider; +import static com.facebook.drawee.drawable.RoundedCornersDrawable.Type.CLIPPING; + import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Build; +import com.facebook.drawee.drawable.RoundedCornersDrawable; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.common.MapBuilder; @@ -146,4 +149,26 @@ public static Map getExportedCustomDirectEventTypeConstants() { ReactSlidingCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", ReactSlidingCompleteEvent.EVENT_NAME) ); } + + public static void setSliderThickness(ReactSlider view, double value) { + LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent(); + for (int i = 0; i < drawable.getNumberOfLayers(); i ++ ) { + // 0 is max/background progress; 1 is ???; 2 is min/current progress + drawable.setLayerHeight(i, (int) value); + } + } + + public static void setSliderCornerRoundness(ReactSlider view, double value) { + LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent(); + for (int i = 0; i < drawable.getNumberOfLayers(); i ++ ) { + RoundedCornersDrawable newDrawable = new RoundedCornersDrawable(drawable.getDrawable(i)); + newDrawable.setRadius((float) value); + newDrawable.setType(CLIPPING); + drawable.setDrawable(i, newDrawable); + } + } + public static void setThumbSize(ReactSlider view, double w, double h) { + view.thumbDrawable.setDimension(w, h); + } + } diff --git a/package/android/src/main/java/com/reactnativecommunity/slider/ThumbDrawable.java b/package/android/src/main/java/com/reactnativecommunity/slider/ThumbDrawable.java new file mode 100644 index 00000000..f41c0a47 --- /dev/null +++ b/package/android/src/main/java/com/reactnativecommunity/slider/ThumbDrawable.java @@ -0,0 +1,76 @@ +package com.reactnativecommunity.slider; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.facebook.drawee.drawable.ForwardingDrawable; + +import java.util.Objects; + + +public class ThumbDrawable extends ForwardingDrawable { + private final Paint mPaint = new Paint(); + private int width = 0; + private int height = 0; + private float rx = 100; + private float ry = 100; + + /** + * Constructs a new forwarding drawable. + * + * @param drawable drawable that this forwarding drawable will forward to + */ + public ThumbDrawable(@Nullable Drawable drawable) { + super(drawable); + mPaint.setColor(Color.RED); + } + + @Override + public void draw(@NonNull Canvas canvas) { + if (width == 0 || height == 0) { + super.draw(canvas); + return; + } + Rect defaultRect = Objects.requireNonNull(getDrawable()).getBounds(); + // LEFT, TOP, RIGHT, BOTTOM. so its actually at (left+(Right - left) / 2, top+(bottom - top) / 2) + // with width = right - left and height = bottom - top + float newLeft = defaultRect.left + (defaultRect.right - defaultRect.left) / 2f - width / 2f; + float newTop = defaultRect.top + (defaultRect.bottom - defaultRect.top) / 2f - height / 2f; + + canvas.drawRoundRect( + newLeft, + newTop, + newLeft + width, + newTop + height, + rx, ry, mPaint); + } + + @Override + public void setColorFilter(@Nullable ColorFilter colorFilter) { + mPaint.setColorFilter(colorFilter); + super.setColorFilter(colorFilter); + } + + @Override + public void clearColorFilter() { + mPaint.setColorFilter(null); + super.clearColorFilter(); + } + + public void setDimension(double width, double height) { + this.width = (int) width; + this.height = (int) height; + } + + public void setCornerRoundness(double rx, double ry) { + this.rx = (float) rx; + this.ry = (float) ry; + } +} diff --git a/package/src/RNCSliderNativeComponent.ts b/package/src/RNCSliderNativeComponent.ts index c63f8d5e..92eaf9dd 100644 --- a/package/src/RNCSliderNativeComponent.ts +++ b/package/src/RNCSliderNativeComponent.ts @@ -40,6 +40,9 @@ export interface NativeProps extends ViewProps { value?: Float; lowerLimit?: Float; upperLimit?: Float; + sliderThickness?: Double; + sliderCornerRoundness?: Double; + thumbSize?: Double; } export default codegenNativeComponent('RNCSlider', { diff --git a/package/src/Slider.tsx b/package/src/Slider.tsx index a18185de..c2153702 100644 --- a/package/src/Slider.tsx +++ b/package/src/Slider.tsx @@ -38,6 +38,22 @@ type WindowsProps = Readonly<{ vertical?: boolean; }>; + +type AndroidProps = Readonly<{ + /** + * modifies slider thickness. Android only. + */ + sliderThickness?: number; + /** + * modifies slider corner roundness. Android only. + */ + sliderCornerRoundness?: number; + /** + * modifies thumb size. Android only. + */ + thumbSize?: number; +}>; + type IOSProps = Readonly<{ /** * Assigns a single image for the track. Only static images are supported. @@ -67,6 +83,7 @@ type IOSProps = Readonly<{ type Props = ViewProps & IOSProps & WindowsProps & + AndroidProps & Readonly<{ /** * Used to style and layout the `Slider`. See `StyleSheet.js` and diff --git a/package/typings/index.d.ts b/package/typings/index.d.ts index 0b548440..fc8aa0bd 100644 --- a/package/typings/index.d.ts +++ b/package/typings/index.d.ts @@ -14,6 +14,18 @@ export interface SliderPropsAndroid extends ReactNative.ViewProps { * Color of the foreground switch grip. */ thumbTintColor?: string; + /** + * modifies slider thickness. Android only. + */ + sliderThickness?: number; + /** + * modifies slider corner roundness. Android only. + */ + sliderCornerRoundness?: number; + /** + * modifies thumb size. Android only. + */ + thumbSize?: number; } export interface SliderRef {