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 https://github.com/facebook/react-native/pull/12280 Differential Revision: D4571858 Pulled By: astreet fbshipit-source-id: 7dca2db33a0a4eecb6115b45155549b1265ffbed
This commit is contained in:
parent
a2addbd932
commit
ae57b25134
|
@ -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 @@ package com.facebook.react.views.textinput;
|
|||
|
||||
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 class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
|||
} 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)
|
||||
|
|
Loading…
Reference in New Issue