mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix selectionColor doesn't style Android TextInput selection handles (#31007)
Summary: This issue fixes https://github.com/facebook/react-native/issues/30283 selectionColor does not change the handles color. The method setCursorColor changes the cursor color of field `mCursorDrawable` using a reflection for Android Devices lower then API 28. This fix adds a reflection to change color of the left, center and right handles of a selection (mTextSelectHandleLeftRes, mTextSelectHandleRes and mTextSelectHandleRightRes). ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [Android] [Fixed] - Fix selectionColor doesn't style Android TextInput selection handles Pull Request resolved: https://github.com/facebook/react-native/pull/31007 Test Plan: This changes fix the Java API for which I can not write Java tests as explained in commit https://github.com/facebook/react-native/commit/709a441ecf54cd9465f5946af0454ee7d10d5cbe The java TextInputTest was excluded from the test suite in commit https://github.com/facebook/react-native/commit/709a441ecf54cd9465f5946af0454ee7d10d5cbe as they need the Yoga libraries to run **<details><summary>CLICK TO OPEN TESTS RESULTS - API 22</summary>** <p> left/right handles do not change color with the cursor | **BEFORE** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/108241887-98351180-714c-11eb-9c7b-7c693ea0bb06.png" width="250" height="" /> | center Handle color does not change color | **BEFORE** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/108241904-9ec38900-714c-11eb-9fc3-dbd26f83b979.png" width="250" height="" /> | The left and right handle change color with the cursor color | **AFTER** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/108241796-805d8d80-714c-11eb-9d90-6871ddaea86f.png" width="250" height="" /> | The center handle color is correctly updated | **AFTER** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/108241571-45f3f080-714c-11eb-8475-86e6dea64d73.png" width="250" height="" /> | `setCursorColor` changes correctly the cursor color | **AFTER** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/108241484-2d83d600-714c-11eb-8a0c-80a847f28537.png" width="250" height="" /> | Default Colors do not have issues | **AFTER** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/108241346-04634580-714c-11eb-933e-0dce504498a8.png" width="250" height="" /> | | **AFTER** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/108241347-04fbdc00-714c-11eb-902a-fc057cf94986.png" width="250" height="" /> | </p> </details> Reviewed By: ShikaSD Differential Revision: D28682935 Pulled By: sota000 fbshipit-source-id: ff037c93f36bbf20c915373b995bbfd8e8ca92d0
This commit is contained in:
committed by
Facebook GitHub Bot
parent
c29ec46b0e
commit
5819538a08
+41
-26
@@ -158,6 +158,15 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
private static final String KEYBOARD_TYPE_URI = "url";
|
||||
private static final InputFilter[] EMPTY_FILTERS = new InputFilter[0];
|
||||
private static final int UNSET = -1;
|
||||
private static final String[] DRAWABLE_FIELDS = {
|
||||
"mCursorDrawable", "mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"
|
||||
};
|
||||
private static final String[] DRAWABLE_RESOURCES = {
|
||||
"mCursorDrawableRes",
|
||||
"mTextSelectHandleLeftRes",
|
||||
"mTextSelectHandleRightRes",
|
||||
"mTextSelectHandleRes"
|
||||
};
|
||||
|
||||
protected @Nullable ReactTextViewManagerCallback mReactTextViewManagerCallback;
|
||||
|
||||
@@ -507,34 +516,40 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
}
|
||||
|
||||
// The evil code that follows uses reflection to achieve this on Android 8.1 and below.
|
||||
// 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);
|
||||
// Based on https://tinyurl.com/3vff8lyu https://tinyurl.com/vehggzs9
|
||||
for (int i = 0; i < DRAWABLE_RESOURCES.length; i++) {
|
||||
try {
|
||||
Field drawableResourceField = TextView.class.getDeclaredField(DRAWABLE_RESOURCES[i]);
|
||||
drawableResourceField.setAccessible(true);
|
||||
int resourceId = drawableResourceField.getInt(view);
|
||||
|
||||
// The view has no cursor drawable.
|
||||
if (drawableResId == 0) {
|
||||
return;
|
||||
// The view has no cursor drawable.
|
||||
if (resourceId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Drawable drawable = ContextCompat.getDrawable(view.getContext(), resourceId);
|
||||
|
||||
Drawable drawableCopy = drawable.mutate();
|
||||
drawableCopy.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
|
||||
Field editorField = TextView.class.getDeclaredField("mEditor");
|
||||
editorField.setAccessible(true);
|
||||
Object editor = editorField.get(view);
|
||||
|
||||
Field cursorDrawableField = editor.getClass().getDeclaredField(DRAWABLE_FIELDS[i]);
|
||||
cursorDrawableField.setAccessible(true);
|
||||
if (DRAWABLE_RESOURCES[i] == "mCursorDrawableRes") {
|
||||
Drawable[] drawables = {drawableCopy, drawableCopy};
|
||||
cursorDrawableField.set(editor, drawables);
|
||||
} else {
|
||||
cursorDrawableField.set(editor, drawableCopy);
|
||||
}
|
||||
} catch (NoSuchFieldException ex) {
|
||||
// Ignore errors to avoid crashing if these private fields don't exist on modified
|
||||
// or future android versions.
|
||||
} catch (IllegalAccessException ex) {
|
||||
}
|
||||
|
||||
Drawable drawable = ContextCompat.getDrawable(view.getContext(), drawableResId);
|
||||
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) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user