Permalink
Browse files

Change cursor color when using selectionColor on Android

Summary:
This matches the behavior on iOS, there was no way before to change the cursor color per input, it was only possible to change it globally via the theme. Ideally cursor color and selection color would be 2 different props but I think this is better than what we have (and matches iOS).

Sadly there is no api to change it pragmatically (only possible via xml) so this uses reflection and can easily break so it is wrapped in a try catch to avoid crashes. I think it is better to just silently fail in this case. Definetly not super happy about the solution but I think it's worth adding since it is possible to do it natively using xml so it would suck not to be able to do it in RN.

**Test plan**
Tested that the cursor has the same color as before the change when not setting the prop and that it gets the selectionColor color when set.
Closes #12280

Differential Revision: D4571858

Pulled By: astreet

fbshipit-source-id: 7dca2db33a0a4eecb6115b45155549b1265ffbed
  • Loading branch information...
janicduplessis authored and facebook-github-bot committed Feb 16, 2017
1 parent a2addbd commit ae57b25134c4db8be8539a0f0e6e52d46c850339
@@ -409,7 +409,7 @@ const TextInput = React.createClass({
*/
secureTextEntry: PropTypes.bool,
/**
* The highlight (and cursor on iOS) color of the text input.
* The highlight and cursor color of the text input.
*/
selectionColor: ColorPropType,
/**
@@ -5,6 +5,7 @@ android_library(
srcs = glob(['*.java']),
deps = [
YOGA_TARGET,
react_native_dep('third-party/android/support/v4:lib-support-v4'),
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_target('java/com/facebook/react/bridge:bridge'),
@@ -22,4 +23,3 @@ android_library(
'PUBLIC',
],
)
@@ -11,11 +11,14 @@
import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.Map;
import android.graphics.drawable.Drawable;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
@@ -310,6 +313,37 @@ public void setSelectionColor(ReactEditText view, @Nullable Integer color) {
} else {
view.setHighlightColor(color);
}
setCursorColor(view, color);
}
private void setCursorColor(ReactEditText view, @Nullable Integer color) {
// Evil method that uses reflection because there is no public API to changes
// the cursor color programmatically.
// Based on http://stackoverflow.com/questions/25996032/how-to-change-programatically-edittext-cursor-color-in-android.
try {
// Get the original cursor drawable resource.
Field cursorDrawableResField = TextView.class.getDeclaredField("mCursorDrawableRes");
cursorDrawableResField.setAccessible(true);
int drawableResId = cursorDrawableResField.getInt(view);
Drawable drawable = ContextCompat.getDrawable(view.getContext(), drawableResId);
if (color != null) {
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
Drawable[] drawables = {drawable, drawable};
// Update the current cursor drawable with the new one.
Field editorField = TextView.class.getDeclaredField("mEditor");
editorField.setAccessible(true);
Object editor = editorField.get(view);
Field cursorDrawableField = editor.getClass().getDeclaredField("mCursorDrawable");
cursorDrawableField.setAccessible(true);
cursorDrawableField.set(editor, drawables);
} catch (NoSuchFieldException ex) {
// Ignore errors to avoid crashing if these private fields don't exist on modified
// or future android versions.
} catch (IllegalAccessException ex) {}
}
@ReactProp(name = "selectTextOnFocus", defaultBoolean = false)

2 comments on commit ae57b25

@krailler

This comment has been minimized.

Show comment
Hide comment
@krailler

krailler Apr 17, 2017

I have this issue, #13465 :/

I have this issue, #13465 :/

@slorber

This comment has been minimized.

Show comment
Hide comment
@slorber

slorber Jul 18, 2018

Contributor

@janicduplessis what about having a different colors for selection and cursor?

Basically I want my cursor to be the same color of the text. Which means obviously that selecting the text will make it invisibible (ie, red text on red selection rectangle)

Contributor

slorber replied Jul 18, 2018

@janicduplessis what about having a different colors for selection and cursor?

Basically I want my cursor to be the same color of the text. Which means obviously that selecting the text will make it invisibible (ie, red text on red selection rectangle)

Please sign in to comment.