Fix an issue with removeClippedSubviews and TextInput
Summary:This issue was found by brentvatne in https://github.com/facebook/react-native/issues/6805 The problem is an ordering issue. The internal state of the TextView (Editor) is updated when we set the text value for a ReactTextInput. When removeClippedSubviews is false, we addView the view which attaches it to the window, and then set the text. When removeClippedSubviews is false, we defer adding the view (caching it in mAllChildren in ReactViewGroup) until we know whether the view is actually going to show. This means when we set the initial text, that there is no window attached. Not having a window attached means that the Editor can't display the popup for PASTE and thinks that the text is not selectable and won't respond to the long press. To fix this we explicitly call setTextIsSelectable in onAttachedToWindow. This will cause the underlying TextView to have the Editor update and all will be in agreement. Note: This also makes it really easy to expose a selectable property on both Text and TextInput at the js level now. Reviewed By: andreicoman11 Differential Revision: D3173631 fb-gh-sync-id: a208214474a92ecc1277b3be0d38e2ef9327ea2e fbshipit-source-id: a208214474a92ecc1277b3be0d38e2ef9327ea2e
This commit is contained in:
parent
a8f4159fc7
commit
89340f1620
|
@ -23,6 +23,7 @@ public class ReactTextView extends TextView implements ReactCompoundView {
|
||||||
private boolean mContainsImages;
|
private boolean mContainsImages;
|
||||||
private int mDefaultGravityHorizontal;
|
private int mDefaultGravityHorizontal;
|
||||||
private int mDefaultGravityVertical;
|
private int mDefaultGravityVertical;
|
||||||
|
private boolean mTextIsSelectable;
|
||||||
|
|
||||||
public ReactTextView(Context context) {
|
public ReactTextView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -81,6 +82,12 @@ public class ReactTextView extends TextView implements ReactCompoundView {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTextIsSelectable(boolean selectable) {
|
||||||
|
mTextIsSelectable = selectable;
|
||||||
|
super.setTextIsSelectable(selectable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean verifyDrawable(Drawable drawable) {
|
protected boolean verifyDrawable(Drawable drawable) {
|
||||||
if (mContainsImages && getText() instanceof Spanned) {
|
if (mContainsImages && getText() instanceof Spanned) {
|
||||||
|
@ -136,6 +143,7 @@ public class ReactTextView extends TextView implements ReactCompoundView {
|
||||||
@Override
|
@Override
|
||||||
public void onAttachedToWindow() {
|
public void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
|
setTextIsSelectable(mTextIsSelectable);
|
||||||
if (mContainsImages && getText() instanceof Spanned) {
|
if (mContainsImages && getText() instanceof Spanned) {
|
||||||
Spanned text = (Spanned) getText();
|
Spanned text = (Spanned) getText();
|
||||||
TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class);
|
TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class);
|
||||||
|
|
|
@ -66,6 +66,7 @@ public class ReactEditText extends EditText {
|
||||||
private @Nullable ArrayList<TextWatcher> mListeners;
|
private @Nullable ArrayList<TextWatcher> mListeners;
|
||||||
private @Nullable TextWatcherDelegator mTextWatcherDelegator;
|
private @Nullable TextWatcherDelegator mTextWatcherDelegator;
|
||||||
private int mStagedInputType;
|
private int mStagedInputType;
|
||||||
|
private boolean mTextIsSelectable = true;
|
||||||
private boolean mContainsImages;
|
private boolean mContainsImages;
|
||||||
private boolean mBlurOnSubmit;
|
private boolean mBlurOnSubmit;
|
||||||
private @Nullable SelectionWatcher mSelectionWatcher;
|
private @Nullable SelectionWatcher mSelectionWatcher;
|
||||||
|
@ -215,6 +216,12 @@ public class ReactEditText extends EditText {
|
||||||
setKeyListener(mKeyListener);
|
setKeyListener(mKeyListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTextIsSelectable(boolean selectable) {
|
||||||
|
mTextIsSelectable = selectable;
|
||||||
|
super.setTextIsSelectable(selectable);
|
||||||
|
}
|
||||||
|
|
||||||
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
||||||
public void requestFocusFromJS() {
|
public void requestFocusFromJS() {
|
||||||
mIsJSSettingFocus = true;
|
mIsJSSettingFocus = true;
|
||||||
|
@ -389,6 +396,7 @@ public class ReactEditText extends EditText {
|
||||||
@Override
|
@Override
|
||||||
public void onAttachedToWindow() {
|
public void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
|
setTextIsSelectable(mTextIsSelectable);
|
||||||
if (mContainsImages && getText() instanceof Spanned) {
|
if (mContainsImages && getText() instanceof Spanned) {
|
||||||
Spanned text = (Spanned) getText();
|
Spanned text = (Spanned) getText();
|
||||||
TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class);
|
TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class);
|
||||||
|
|
Loading…
Reference in New Issue