Support customizing thumb, track and progress colors for slider on Android

Summary:
**Motivation**

Ability to customize slider colors is desirable to match the brand. Currently iOS allows using images for slider parts, but android doesn't have any customization options. This PR adds support for customizing `thumbTintColor`, `trackTintColor` and `progressTintColor`.

**Test plan (required)**

Run UIExplorer example with the changes and verify everything works fine.

![image](https://cloud.githubusercontent.com/assets/1174278/22020752/f32a6eec-dcdf-11e6-928d-481bb28bd0a3.png)

cc brentvatne
Closes https://github.com/facebook/react-native/pull/11946

Differential Revision: D4427474

fbshipit-source-id: ec3a38db600bac6108691a4cfa15e2409143b9f3
This commit is contained in:
Satyajit Sahoo 2017-02-01 00:36:08 -08:00 committed by Facebook Github Bot
parent d1990f8fc4
commit 295a0150d4
5 changed files with 66 additions and 17 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

@ -132,16 +132,23 @@ exports.examples = [
}, },
{ {
title: 'Custom min/max track tint color', title: 'Custom min/max track tint color',
platform: 'ios',
render(): React.Element<any> { render(): React.Element<any> {
return ( return (
<SliderExample <SliderExample
minimumTrackTintColor={'red'} minimumTrackTintColor={'blue'}
maximumTrackTintColor={'green'} maximumTrackTintColor={'red'}
value={0.5}
/> />
); );
} }
}, },
{
title: 'Custom thumb color',
platform: 'android',
render(): React.Element<any> {
return <SliderExample thumbTintColor={'blue'} />;
}
},
{ {
title: 'Custom thumb image', title: 'Custom thumb image',
platform: 'ios', platform: 'ios',

View File

@ -12,6 +12,7 @@
'use strict'; 'use strict';
var Image = require('Image'); var Image = require('Image');
var ColorPropType = require('ColorPropType');
var NativeMethodsMixin = require('NativeMethodsMixin'); var NativeMethodsMixin = require('NativeMethodsMixin');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var Platform = require('Platform'); var Platform = require('Platform');
@ -68,18 +69,16 @@ var Slider = React.createClass({
maximumValue: PropTypes.number, maximumValue: PropTypes.number,
/** /**
* The color used for the track to the left of the button. Overrides the * The color used for the track to the left of the button.
* default blue gradient image. * Overrides the default blue gradient image on iOS.
* @platform ios
*/ */
minimumTrackTintColor: PropTypes.string, minimumTrackTintColor: ColorPropType,
/** /**
* The color used for the track to the right of the button. Overrides the * The color used for the track to the right of the button.
* default blue gradient image. * Overrides the default blue gradient image on iOS.
* @platform ios
*/ */
maximumTrackTintColor: PropTypes.string, maximumTrackTintColor: ColorPropType,
/** /**
* If true the user won't be able to move the slider. * If true the user won't be able to move the slider.
@ -114,6 +113,12 @@ var Slider = React.createClass({
*/ */
thumbImage: Image.propTypes.source, thumbImage: Image.propTypes.source,
/**
* Color of the foreground switch grip.
* @platform android
*/
thumbTintColor: ColorPropType,
/** /**
* Callback continuously called while the user is dragging the slider. * Callback continuously called while the user is dragging the slider.
*/ */

View File

@ -9,16 +9,16 @@
package com.facebook.react.views.slider; package com.facebook.react.views.slider;
import java.util.Map; import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.TypedValue;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.SeekBar; import android.widget.SeekBar;
import com.facebook.yoga.YogaMeasureMode; import com.facebook.react.R;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaNodeAPI;
import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.MapBuilder; import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.LayoutShadowNode; import com.facebook.react.uimanager.LayoutShadowNode;
@ -27,6 +27,12 @@ import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.yoga.YogaNodeAPI;
import java.util.Map;
/** /**
* Manages instances of {@code ReactSlider}. * Manages instances of {@code ReactSlider}.
@ -145,6 +151,37 @@ public class ReactSliderManager extends SimpleViewManager<ReactSlider> {
view.setStep(value); view.setStep(value);
} }
@ReactProp(name = "thumbTintColor", customType = "Color")
public void setThumbTintColor(ReactSlider view, Integer color) {
if (color == null) {
view.getThumb().clearColorFilter();
} else {
view.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
@ReactProp(name = "minimumTrackTintColor", customType = "Color")
public void setMinimumTrackTintColor(ReactSlider view, Integer color) {
LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent();
Drawable background = drawable.findDrawableByLayerId(android.R.id.background);
if (color == null) {
background.clearColorFilter();
} else {
background.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
@ReactProp(name = "maximumTrackTintColor", customType = "Color")
public void setMaximumTrackTintColor(ReactSlider view, Integer color) {
LayerDrawable drawable = (LayerDrawable) view.getProgressDrawable().getCurrent();
Drawable progress = drawable.findDrawableByLayerId(android.R.id.progress);
if (color == null) {
progress.clearColorFilter();
} else {
progress.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
@Override @Override
protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) { protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) {
view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER); view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER);