mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
2030c78355
Reviewed By: marco-cova Differential Revision: D4859822 fbshipit-source-id: 2588c1b3334f28332ae43e6c0bdec65934ca84c4
196 lines
5.7 KiB
Java
196 lines
5.7 KiB
Java
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
package com.facebook.react.flat;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import android.annotation.TargetApi;
|
|
import android.os.Build;
|
|
import android.text.SpannableStringBuilder;
|
|
import android.util.TypedValue;
|
|
import android.view.ViewGroup;
|
|
import android.widget.EditText;
|
|
|
|
import com.facebook.yoga.YogaMeasureMode;
|
|
import com.facebook.yoga.YogaMeasureFunction;
|
|
import com.facebook.yoga.YogaNode;
|
|
import com.facebook.yoga.YogaMeasureOutput;
|
|
import com.facebook.infer.annotation.Assertions;
|
|
import com.facebook.react.uimanager.PixelUtil;
|
|
import com.facebook.react.uimanager.Spacing;
|
|
import com.facebook.react.uimanager.ThemedReactContext;
|
|
import com.facebook.react.uimanager.UIViewOperationQueue;
|
|
import com.facebook.react.uimanager.ViewDefaults;
|
|
import com.facebook.react.uimanager.ViewProps;
|
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
import com.facebook.react.views.text.ReactTextUpdate;
|
|
import com.facebook.react.views.view.MeasureUtil;
|
|
|
|
import static com.facebook.react.views.text.ReactTextShadowNode.PROP_TEXT;
|
|
import static com.facebook.react.views.text.ReactTextShadowNode.UNSET;
|
|
|
|
public class RCTTextInput extends RCTVirtualText implements AndroidView, YogaMeasureFunction {
|
|
|
|
@Nullable private String mText;
|
|
private int mJsEventCount = UNSET;
|
|
private boolean mPaddingChanged = false;
|
|
private int mNumberOfLines = UNSET;
|
|
private @Nullable EditText mEditText;
|
|
|
|
public RCTTextInput() {
|
|
forceMountToView();
|
|
setMeasureFunction(this);
|
|
}
|
|
|
|
@Override
|
|
protected void notifyChanged(boolean shouldRemeasure) {
|
|
super.notifyChanged(shouldRemeasure);
|
|
// needed to trigger onCollectExtraUpdates
|
|
markUpdated();
|
|
}
|
|
|
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
|
@Override
|
|
public void setThemedContext(ThemedReactContext themedContext) {
|
|
super.setThemedContext(themedContext);
|
|
|
|
mEditText = new EditText(themedContext);
|
|
// 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
|
|
mEditText.setLayoutParams(
|
|
new ViewGroup.LayoutParams(
|
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
|
|
setDefaultPadding(Spacing.START, mEditText.getPaddingStart());
|
|
setDefaultPadding(Spacing.TOP, mEditText.getPaddingTop());
|
|
setDefaultPadding(Spacing.END, mEditText.getPaddingEnd());
|
|
setDefaultPadding(Spacing.BOTTOM, mEditText.getPaddingBottom());
|
|
mEditText.setPadding(0, 0, 0, 0);
|
|
}
|
|
|
|
@Override
|
|
public long measure(
|
|
YogaNode node,
|
|
float width,
|
|
YogaMeasureMode widthMode,
|
|
float height,
|
|
YogaMeasureMode heightMode) {
|
|
// measure() should never be called before setThemedContext()
|
|
EditText editText = Assertions.assertNotNull(mEditText);
|
|
|
|
int fontSize = getFontSize();
|
|
editText.setTextSize(
|
|
TypedValue.COMPLEX_UNIT_PX,
|
|
fontSize == UNSET ?
|
|
(int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : fontSize);
|
|
|
|
if (mNumberOfLines != UNSET) {
|
|
editText.setLines(mNumberOfLines);
|
|
}
|
|
|
|
editText.measure(
|
|
MeasureUtil.getMeasureSpec(width, widthMode),
|
|
MeasureUtil.getMeasureSpec(height, heightMode));
|
|
return YogaMeasureOutput.make(editText.getMeasuredWidth(), editText.getMeasuredHeight());
|
|
}
|
|
|
|
@Override
|
|
public boolean isVirtual() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isVirtualAnchor() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void setBackgroundColor(int backgroundColor) {
|
|
// suppress, this is handled by a ViewManager
|
|
}
|
|
|
|
@Override
|
|
public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) {
|
|
super.onCollectExtraUpdates(uiViewOperationQueue);
|
|
if (mJsEventCount != UNSET) {
|
|
ReactTextUpdate reactTextUpdate =
|
|
new ReactTextUpdate(
|
|
getText(),
|
|
mJsEventCount,
|
|
false,
|
|
getPadding(Spacing.START),
|
|
getPadding(Spacing.TOP),
|
|
getPadding(Spacing.END),
|
|
getPadding(Spacing.BOTTOM),
|
|
UNSET);
|
|
// TODO: the Float.NaN should be replaced with the real line height see D3592781
|
|
uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate);
|
|
}
|
|
}
|
|
|
|
@ReactProp(name = "mostRecentEventCount")
|
|
public void setMostRecentEventCount(int mostRecentEventCount) {
|
|
mJsEventCount = mostRecentEventCount;
|
|
}
|
|
|
|
@ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = Integer.MAX_VALUE)
|
|
public void setNumberOfLines(int numberOfLines) {
|
|
mNumberOfLines = numberOfLines;
|
|
notifyChanged(true);
|
|
}
|
|
|
|
@ReactProp(name = PROP_TEXT)
|
|
public void setText(@Nullable String text) {
|
|
mText = text;
|
|
notifyChanged(true);
|
|
}
|
|
|
|
@Override
|
|
public void setPadding(int spacingType, float padding) {
|
|
super.setPadding(spacingType, padding);
|
|
mPaddingChanged = true;
|
|
dirty();
|
|
}
|
|
|
|
@Override
|
|
public boolean isPaddingChanged() {
|
|
return mPaddingChanged;
|
|
}
|
|
|
|
@Override
|
|
public void resetPaddingChanged() {
|
|
mPaddingChanged = false;
|
|
}
|
|
|
|
@Override
|
|
boolean shouldAllowEmptySpans() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
boolean isEditable() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected void performCollectText(SpannableStringBuilder builder) {
|
|
if (mText != null) {
|
|
builder.append(mText);
|
|
}
|
|
super.performCollectText(builder);
|
|
}
|
|
|
|
@Override
|
|
public boolean needsCustomLayoutForChildren() {
|
|
return false;
|
|
}
|
|
}
|