Skip to content

Commit

Permalink
Support tintColor and thumbTintColor for Switch on Android
Browse files Browse the repository at this point in the history
Summary:
**Motivation**

`Switch` on Android doesn't allow changing the colors unlike iOS. Changing the colors is desirable in a lot of cases to match the brand colors.

The PR adds support for the `tintColor`, `onTintColor` and `thumbTintColor` props on Android, which more or less behave the same as iOS. The only difference is `tintColor` styles the border color on iOS, whereas it styles the background color on Android.

**Test plan (required)**

Run UIExplorer with the changes, and ensure that the switch example works properly. Here are screenshots from iOS and Android to compare.

![image](https://cloud.githubusercontent.com/assets/1174278/22018002/b05d6482-dcd2-11e6-9c00-f55a71d6ce29.png)

![image](https://cloud.githubusercontent.com/assets/1174278/22018012/b923e974-dcd2-11e6-8d4e-86994f5a66e6.png)

cc brentvatne
Closes #11940

Differential Revision: D4427491

fbshipit-source-id: 16c569d2e2261daaea93fffa83198f8f6b59a6c8
  • Loading branch information
satya164 authored and facebook-github-bot committed Jan 31, 2017
1 parent 1beb627 commit 31099aa
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
11 changes: 4 additions & 7 deletions Examples/UIExplorer/js/SwitchExample.js
Expand Up @@ -147,15 +147,12 @@ var examples = [
{
title: 'Switches are controlled components',
render(): React.Element<any> { return <Switch />; }
}
];

if (Platform.OS === 'ios') {
examples.push({
},
{
title: 'Custom colors can be provided',
render(): React.Element<any> { return <ColorSwitchExample />; }
});
}
}
];

exports.title = '<Switch>';
exports.displayName = 'SwitchExample';
Expand Down
27 changes: 17 additions & 10 deletions Libraries/Components/Switch/Switch.js
Expand Up @@ -20,6 +20,8 @@ var View = require('View');

var requireNativeComponent = require('requireNativeComponent');

var { PropTypes } = React;

type DefaultProps = {
value: boolean,
disabled: boolean,
Expand All @@ -43,34 +45,31 @@ var Switch = React.createClass({
* The value of the switch. If true the switch will be turned on.
* Default value is false.
*/
value: React.PropTypes.bool,
value: PropTypes.bool,
/**
* If true the user won't be able to toggle the switch.
* Default value is false.
*/
disabled: React.PropTypes.bool,
disabled: PropTypes.bool,
/**
* Invoked with the new value when the value changes.
*/
onValueChange: React.PropTypes.func,
onValueChange: PropTypes.func,
/**
* Used to locate this view in end-to-end tests.
*/
testID: React.PropTypes.string,
testID: PropTypes.string,

/**
* Border color when the switch is turned off.
* @platform ios
* Border color on iOS and background color on Android when the switch is turned off.
*/
tintColor: ColorPropType,
/**
* Background color when the switch is turned on.
* @platform ios
*/
onTintColor: ColorPropType,
/**
* Color of the foreground switch grip.
* @platform ios
*/
thumbTintColor: ColorPropType,
},
Expand Down Expand Up @@ -104,6 +103,7 @@ var Switch = React.createClass({
props.enabled = !this.props.disabled;
props.on = this.props.value;
props.style = this.props.style;
props.trackTintColor = this.props.value ? this.props.onTintColor : this.props.tintColor;
} else if (Platform.OS === 'ios') {
props.style = [styles.rctSwitchIOS, this.props.style];
}
Expand All @@ -126,11 +126,18 @@ var styles = StyleSheet.create({

if (Platform.OS === 'android') {
var RCTSwitch = requireNativeComponent('AndroidSwitch', Switch, {
nativeOnly: { onChange: true, on: true, enabled: true }
nativeOnly: {
onChange: true,
on: true,
enabled: true,
trackTintColor: true,
}
});
} else {
var RCTSwitch = requireNativeComponent('RCTSwitch', Switch, {
nativeOnly: { onChange: true }
nativeOnly: {
onChange: true
}
});
}

Expand Down
Expand Up @@ -10,6 +10,7 @@
// switchview because switch is a keyword
package com.facebook.react.views.switchview;

import android.graphics.PorterDuff;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
Expand Down Expand Up @@ -117,6 +118,24 @@ public void setOn(ReactSwitch view, boolean on) {
view.setOnCheckedChangeListener(ON_CHECKED_CHANGE_LISTENER);
}

@ReactProp(name = "thumbTintColor", customType = "Color")
public void setThumbTintColor(ReactSwitch view, Integer color) {
if (color == null) {
view.getThumbDrawable().clearColorFilter();
} else {
view.getThumbDrawable().setColorFilter(color, PorterDuff.Mode.MULTIPLY);
}
}

@ReactProp(name = "trackTintColor", customType = "Color")
public void setTrackTintColor(ReactSwitch view, Integer color) {
if (color == null) {
view.getTrackDrawable().clearColorFilter();
} else {
view.getTrackDrawable().setColorFilter(color, PorterDuff.Mode.MULTIPLY);
}
}

@Override
protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSwitch view) {
view.setOnCheckedChangeListener(ON_CHECKED_CHANGE_LISTENER);
Expand Down

0 comments on commit 31099aa

Please sign in to comment.