From 77305cadf0442b814ab2f661c37d77188cc8965b Mon Sep 17 00:00:00 2001 From: Matt Chowning Date: Tue, 21 Jan 2020 14:51:21 -0800 Subject: [PATCH] Allow overriding EditText construction in ReactTextInputShadowNode (#27782) Summary: This PR makes it possible for subclasses of `ReactTextInputShadowNode` to control the construction of the "dummy" `EditText` instance that `ReactTextInputShadowNode` internally uses to determine the expected height of the view. This PR does not change the default behavior, it just opens up that default to being overriden. This is useful in the case of custom views that have different behavior from a "default" `EditText` instance (`new EditText(context)`). For example, it might have a different style applied. As a side benefit, this change also makes it easy to have subclasses not apply the default theme, which can allow the custom view to avoid a longstanding crash issue (https://github.com/facebook/react-native/issues/17530). ## Changelog [Android] [Added] - Allow overriding `EditText` construction in `ReactTextInputShadowNode` Pull Request resolved: https://github.com/facebook/react-native/pull/27782 Test Plan: All tests pass. Reviewed By: mdvacca Differential Revision: D19450593 Pulled By: JoshuaGross fbshipit-source-id: 8d2ce6117246fc3e2108623312b38583af5722b3 --- .../textinput/ReactTextInputShadowNode.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java index eeda18dedf5..f722bf6a163 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java @@ -37,7 +37,7 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode implements YogaMeasureFunction { private int mMostRecentEventCount = UNSET; - private @Nullable EditText mDummyEditText; + private @Nullable EditText mInternalEditText; private @Nullable ReactTextInputLocalData mLocalData; @VisibleForTesting public static final String PROP_TEXT = "text"; @@ -75,20 +75,20 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode // of Android), and it cannot be changed. // So, we have to enforce it as a default padding. // TODO #7120264: Cache this stuff better. - EditText editText = new EditText(getThemedContext()); + EditText editText = createInternalEditText(); setDefaultPadding(Spacing.START, ViewCompat.getPaddingStart(editText)); setDefaultPadding(Spacing.TOP, editText.getPaddingTop()); setDefaultPadding(Spacing.END, ViewCompat.getPaddingEnd(editText)); setDefaultPadding(Spacing.BOTTOM, editText.getPaddingBottom()); - mDummyEditText = editText; + mInternalEditText = editText; // We must measure the EditText without paddings, so we have to reset them. - mDummyEditText.setPadding(0, 0, 0, 0); + mInternalEditText.setPadding(0, 0, 0, 0); // This is needed to fix an android bug since 4.4.3 which will throw an NPE in measure, // setting the layoutParams fixes it: https://code.google.com/p/android/issues/detail?id=75877 - mDummyEditText.setLayoutParams( + mInternalEditText.setLayoutParams( new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } @@ -101,7 +101,7 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode float height, YogaMeasureMode heightMode) { // measure() should never be called before setThemedContext() - EditText editText = Assertions.assertNotNull(mDummyEditText); + EditText editText = Assertions.assertNotNull(mInternalEditText); if (mLocalData != null) { mLocalData.apply(editText); @@ -249,4 +249,12 @@ public class ReactTextInputShadowNode extends ReactBaseTextShadowNode super.setPadding(spacingType, padding); markUpdated(); } + + /** + * May be overriden by subclasses that would like to provide their own instance of the internal + * {@code EditText} this class uses to determine the expected size of the view. + */ + protected EditText createInternalEditText() { + return new EditText(getThemedContext()); + } }