support checkbox tinting (#18300)

Summary:
RN offers checkbox component on android: https://facebook.github.io/react-native/docs/checkbox.html

The Checkbox colors for checked and unchecked states cannot be controlled from JS at the moment; this PR adds support for that.

The essence of changing colors for the states is this:

```
ColorStateList cls = new ColorStateList(
        new int[][] {
                new int[] { -android.R.attr.state_checked }, // unchecked
                new int[] {  android.R.attr.state_checked }  // checked
        },
        new int[] {
                uncheckedColor,
                checkedColor
        }
);
checkBox.setSupportButtonTintList(cls);
```

Because of this, I did it so that both colors have to provided together in an object. This is similar to [switch](https://facebook.github.io/react-native/docs/switch#trackcolor)
Pull Request resolved: https://github.com/facebook/react-native/pull/18300

Differential Revision: D14180218

Pulled By: cpojer

fbshipit-source-id: 88a9d1faf061c0651e3e28950f697535b90fbfd4
This commit is contained in:
Vojtech Novak
2019-02-21 20:11:58 -08:00
committed by Facebook Github Bot
parent 17082d92cf
commit 976f4be457
4 changed files with 78 additions and 3 deletions
@@ -7,15 +7,22 @@
package com.facebook.react.views.checkbox;
import android.content.Context;
import android.content.res.ColorStateList;
import android.support.v4.widget.CompoundButtonCompat;
import android.support.v7.widget.TintContextWrapper;
import android.util.TypedValue;
import android.widget.CompoundButton;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
/** View manager for {@link ReactCheckBox} components. */
public class ReactCheckBoxManager extends SimpleViewManager<ReactCheckBox> {
@@ -72,4 +79,44 @@ public class ReactCheckBoxManager extends SimpleViewManager<ReactCheckBox> {
view.setOn(on);
view.setOnCheckedChangeListener(ON_CHECKED_CHANGE_LISTENER);
}
private static int getThemeColor(final Context context, String colorId) {
final TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(getIdentifier(context, colorId), value, true);
return value.data;
}
/**
* The appcompat-v7 BUCK dep is listed as a provided_dep, which complains that
* com.facebook.react.R doesn't exist. Since the attributes are provided from a parent, we can access
* those attributes dynamically.
*/
private static int getIdentifier(Context context, String name) {
return context.getResources().getIdentifier(name, "attr", context.getPackageName());
}
@ReactProp(name = "tintColors")
public void setTintColors(ReactCheckBox view, @Nullable ReadableMap colorsMap) {
String defaultColorIdOfCheckedState = "colorAccent";
int trueColor = colorsMap == null || !colorsMap.hasKey("true") ?
getThemeColor(view.getContext(), defaultColorIdOfCheckedState) : colorsMap.getInt("true");
String defaultColorIdOfUncheckedState = "colorPrimaryDark";
int falseColor = colorsMap == null || !colorsMap.hasKey("false") ?
getThemeColor(view.getContext(), defaultColorIdOfUncheckedState) : colorsMap.getInt("false");
ColorStateList csl = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_checked},
new int[]{-android.R.attr.state_checked}
},
new int[]{
trueColor,
falseColor,
}
);
CompoundButtonCompat.setButtonTintList(view, csl);
}
}