Skip to content

Adding SecondaryProgress for Android #551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -69,3 +69,6 @@ src/dist
# Expo
.expo
web-build

# VS Code
.vscode
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -97,8 +97,10 @@ To use this library you need to ensure you are using the correct version of Reac
| `onValueChange` | Callback continuously called while the user is dragging the slider. | function | No | |
| `step` | Step value of the slider. The value should be between 0 and (maximumValue - minimumValue). Default value is 0.<br/>On Windows OS the default value is 1% of slider's range (from `minimumValue` to `maximumValue`). | number | No | |
| `maximumTrackTintColor` | The color used for the track to the right of the button.<br/>Overrides the default gray gradient image on iOS. | [color](https://reactnative.dev/docs/colors) | No | |
| `bufferedTrackTintColor` | The color used for the track for the secondaryProgress of the slider component. | [color](https://reactnative.dev/docs/colors) | No | Android |
| `testID` | Used to locate this view in UI automation tests. | string | No | |
| `value` | Write-only property representing the value of the slider. Can be used to programmatically control the position of the thumb. Entered once at the beginning still acts as an initial value. Changing the value programmatically does not trigger any event.<br/>The value should be between minimumValue and maximumValue, which default to 0 and 1 respectively. Default value is 0.<br/>_This is not a controlled component_, you don't need to update the value during dragging. | number | No | |
| `bufferedValue` | Write-only property representing the secondaryProgress of the slider. Entered once at the beginning still acts as an initial value.<br/>The value should be between minimumValue and maximumValue, which default to 0 and 1 respectively. Default value is 0.<br/>_This is not a controlled component_ | number | No | Android |
| `tapToSeek` | Permits tapping on the slider track to set the thumb position.<br/>Defaults to false on iOS. No effect on Android or Windows. | bool | No | iOS |
| `inverted` | Reverses the direction of the slider.<br/>Default value is false. | bool | No | |
| `vertical` | Changes the orientation of the slider to vertical, if set to `true`.<br/>Default value is false. | bool | No | Windows |
14 changes: 14 additions & 0 deletions example/src/Examples.tsx
Original file line number Diff line number Diff line change
@@ -513,6 +513,20 @@ export const examples: Props[] = [
);
},
},
{
title: 'Buffer value on Android',
render() {
return (
<SliderExample
step={1}
minimumValue={0}
maximumValue={100}
bufferedValue={75}
bufferedTrackTintColor="red"
/>
);
},
},
{
title: 'onSlidingStart',
render(): React.ReactElement {
Original file line number Diff line number Diff line change
@@ -57,6 +57,8 @@ public class ReactSlider extends AppCompatSeekBar {
*/
private double mValue = 0;

private double mBufferedValue = 0;

private boolean isSliding = false;

/** If zero it's determined automatically. */
@@ -120,6 +122,11 @@ private void disableStateListAnimatorIfNeeded() {
updateValue();
}

/* package */ void setBufferedValue(double value) {
mBufferedValue = value;
updateAll();
}

/* package */ void setStep(double step) {
mStep = step;
updateAll();
@@ -231,6 +238,7 @@ private void updateAll() {
updateLowerLimit();
updateUpperLimit();
updateValue();
updateBufferedValue();
}

/** Update limit based on props limit, max and min
@@ -263,6 +271,10 @@ private void updateValue() {
setProgress((int) Math.round((mValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps()));
}

private void updateBufferedValue() {
setSecondaryProgress((int) Math.round((mBufferedValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps()));
}

private int getTotalSteps() {
return (int) Math.ceil((mMaxValue - mMinValue) / getStepValue());
}
Original file line number Diff line number Diff line change
@@ -44,6 +44,10 @@ public static void setValue(ReactSlider view, double value) {
}
}

public static void setBufferedValue(ReactSlider view, double value) {
view.setBufferedValue(value);
}

public static void setMinimumValue(ReactSlider view, double value) {
view.setMinValue(value);
}
@@ -116,6 +120,21 @@ public static void setMaximumTrackTintColor(ReactSlider view, Integer color) {
}
}

public static void setBufferedTrackTintColor(ReactSlider view, Integer color) {
LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent();
Drawable secondaryProgress = drawable.findDrawableByLayerId(android.R.id.secondaryProgress);
if (color == null) {
secondaryProgress.clearColorFilter();
} else {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
secondaryProgress.setColorFilter(new PorterDuffColorFilter((int)color, PorterDuff.Mode.SRC_IN));
}
else {
secondaryProgress.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
}

public static void setInverted(ReactSlider view, boolean inverted) {
if (inverted) view.setScaleX(-1f);
else view.setScaleX(1f);
Original file line number Diff line number Diff line change
@@ -106,6 +106,12 @@ public void setValue(ReactSlider view, float value) {
ReactSliderManagerImpl.setValue(view, value);
}

@Override
@ReactProp(name = "bufferedValue", defaultFloat = 0f)
public void setBufferedValue(ReactSlider view, float value) {
ReactSliderManagerImpl.setBufferedValue(view, value);
}

@Override
@ReactProp(name = "minimumValue", defaultFloat = 0f)
public void setMinimumValue(ReactSlider view, double value) {
@@ -136,6 +142,12 @@ public void setMinimumTrackTintColor(ReactSlider view, Integer color) {
ReactSliderManagerImpl.setMinimumTrackTintColor(view, color);
}

@Override
@ReactProp(name = "bufferedTrackTintColor", customType = "Color")
public void setBufferedTrackTintColor(ReactSlider view, Integer color) {
ReactSliderManagerImpl.setBufferedTrackTintColor(view, color);
}

@Override
@ReactProp(name = "maximumTrackTintColor", customType = "Color")
public void setMaximumTrackTintColor(ReactSlider view, Integer color) {
Original file line number Diff line number Diff line change
@@ -125,6 +125,11 @@ public void setValue(ReactSlider view, float value) {
ReactSliderManagerImpl.setValue(view, value);
}

@ReactProp(name = "bufferedValue", defaultDouble = 0d)
public void setBufferedValue(ReactSlider view, double value) {
ReactSliderManagerImpl.setBufferedValue(view, value);
}

@ReactProp(name = "minimumValue", defaultDouble = 0d)
public void setMinimumValue(ReactSlider view, double value) {
ReactSliderManagerImpl.setMinimumValue(view, value);
@@ -160,6 +165,11 @@ public void setMinimumTrackTintColor(ReactSlider view, Integer color) {
ReactSliderManagerImpl.setMinimumTrackTintColor(view, color);
}

@ReactProp(name = "bufferedTrackTintColor", customType = "Color")
public void setBufferedTrackTintColor(ReactSlider view, Integer color) {
ReactSliderManagerImpl.setBufferedTrackTintColor(view, color);
}

@ReactProp(name = "thumbImage")
public void setThumbImage(ReactSlider view, @Nullable ReadableMap source) {
ReactSliderManagerImpl.setThumbImage(view, source);
2 changes: 2 additions & 0 deletions package/src/RNCSliderNativeComponent.ts
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ export interface NativeProps extends ViewProps {
maximumValue?: Double;
minimumTrackImage?: ImageSource;
minimumTrackTintColor?: ColorValue;
bufferedTrackTintColor?: ColorValue;
minimumValue?: Double;
onChange?: BubblingEventHandler<Event>;
onRNCSliderSlidingStart?: DirectEventHandler<Event>;
@@ -38,6 +39,7 @@ export interface NativeProps extends ViewProps {
thumbTintColor?: ColorValue;
trackImage?: ImageSource;
value?: Float;
bufferedValue?: Float;
lowerLimit?: Float;
upperLimit?: Float;
}
12 changes: 12 additions & 0 deletions package/src/Slider.tsx
Original file line number Diff line number Diff line change
@@ -87,6 +87,15 @@ type Props = ViewProps &
*/
value?: number;

/**
* Write-only property representing the secondaryProgress of the slider.
* Entered once at the beginning still acts as an initial value.
* The value should be between minimumValue and maximumValue,
* which default to 0 and 1 respectively.
* Default value is 0.
*/
bufferedValue?: number;

/**
* Step value of the slider. The value should be
* between 0 and (maximumValue - minimumValue).
@@ -120,6 +129,8 @@ type Props = ViewProps &
*/
minimumTrackTintColor?: ColorValue;

bufferedTrackTintColor?: ColorValue;

/**
* The color used for the track to the right of the button.
* Overrides the default blue gradient image on iOS.
@@ -351,6 +362,7 @@ const SliderWithRef = React.forwardRef(SliderComponent);

SliderWithRef.defaultProps = {
value: 0,
bufferedValue: 0,
minimumValue: 0,
maximumValue: 1,
step: 0,
7 changes: 7 additions & 0 deletions package/src/__tests__/__snapshots__/Slider.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ exports[`<Slider /> accessibilityState disabled sets disabled={true} 1`] = `
"disabled": true,
}
}
bufferedValue={0}
disabled={true}
inverted={false}
lowerLimit={-9007199254740991}
@@ -81,6 +82,7 @@ exports[`<Slider /> disabled prop overrides accessibilityState.disabled 1`] = `
"disabled": true,
}
}
bufferedValue={0}
disabled={true}
inverted={false}
lowerLimit={-9007199254740991}
@@ -139,6 +141,7 @@ exports[`<Slider /> disabled prop overrides accessibilityState.enabled 1`] = `
"disabled": false,
}
}
bufferedValue={0}
disabled={false}
inverted={false}
lowerLimit={-9007199254740991}
@@ -192,6 +195,7 @@ exports[`<Slider /> renders a slider with custom props 1`] = `
}
>
<RNCSlider
bufferedValue={0}
disabled={false}
inverted={false}
lowerLimit={0}
@@ -32300,6 +32304,7 @@ exports[`<Slider /> renders a slider with custom stepMaker 1`] = `
</View>
<RNCSlider
StepMarker={[Function]}
bufferedValue={0}
disabled={false}
inverted={false}
lowerLimit={-9007199254740991}
@@ -32358,6 +32363,7 @@ exports[`<Slider /> renders disabled slider 1`] = `
"disabled": true,
}
}
bufferedValue={0}
disabled={true}
inverted={false}
lowerLimit={-9007199254740991}
@@ -32411,6 +32417,7 @@ exports[`<Slider /> renders enabled slider 1`] = `
}
>
<RNCSlider
bufferedValue={0}
disabled={false}
inverted={false}
lowerLimit={-9007199254740991}
21 changes: 18 additions & 3 deletions package/typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { FC } from 'react';
import {FC} from 'react';
import * as ReactNative from 'react-native';
import { ImageURISource } from 'react-native';
import {ImageURISource} from 'react-native';

type Constructor<T> = new (...args: any[]) => T;

@@ -14,6 +14,21 @@ export interface SliderPropsAndroid extends ReactNative.ViewProps {
* Color of the foreground switch grip.
*/
thumbTintColor?: string;

/**
* Write-only property representing the bufferedValue of the slider.
* Entered once at the beginning still acts as an initial value.
* The value should be between minimumValue and maximumValue,
* which default to 0 and 1 respectively.
* Default value is 0.
*/
bufferedValue?: number;

/**
* The color used for the buffered track (secondaryProgress)
* Overrides the default grey gradient image.
*/
bufferedTrackTintColor?: string;
}

export interface SliderRef {
@@ -168,7 +183,7 @@ export interface SliderProps
StepMarker?: FC<MarkerProps>;

/**
*
*
*/
renderStepNumber?: boolean;

Loading
Oops, something went wrong.