@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 long measure( YogaNodeAPI 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 void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) { // measure() should never be called before setThemedContext() EditText editText = Assertions.assertNotNull(mEditText); measureOutput.width = width; editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, mFontSize == UNSET ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : mFontSize); mComputedPadding = spacingToFloatArray(getPadding()); editText.setPadding( (int) Math.ceil(getPadding().get(Spacing.LEFT)), (int) Math.ceil(getPadding().get(Spacing.TOP)), (int) Math.ceil(getPadding().get(Spacing.RIGHT)), (int) Math.ceil(getPadding().get(Spacing.BOTTOM))); if (mNumberOfLines != UNSET) { editText.setLines(mNumberOfLines); } editText.measure(0 /* unspecified */, 0 /* unspecified */); measureOutput.height = editText.getMeasuredHeight(); }
@Override public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) { // measure() should never be called before setThemedContext() EditText editText = Assertions.assertNotNull(mEditText); measureOutput.width = width; editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, mFontSize == UNSET ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : mFontSize); mComputedPadding = spacingToFloatArray(getPadding()); editText.setPadding( (int) Math.ceil(getPadding().get(Spacing.LEFT)), (int) Math.ceil(getPadding().get(Spacing.TOP)), (int) Math.ceil(getPadding().get(Spacing.RIGHT)), (int) Math.ceil(getPadding().get(Spacing.BOTTOM))); if (mNumberOfLines != UNSET) { editText.setLines(mNumberOfLines); } editText.measure(MEASURE_SPEC, MEASURE_SPEC); measureOutput.height = editText.getMeasuredHeight(); }
@Override public ReactEditText createViewInstance(ThemedReactContext context) { ReactEditText editText = new ReactEditText(context); int inputType = editText.getInputType(); editText.setInputType(inputType & (~InputType.TYPE_TEXT_FLAG_MULTI_LINE)); editText.setReturnKeyType("done"); editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP))); return editText; }
@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); editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, mFontSize == UNSET ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : mFontSize); if (mNumberOfLines != UNSET) { editText.setLines(mNumberOfLines); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (editText.getBreakStrategy() != mTextBreakStrategy) { editText.setBreakStrategy(mTextBreakStrategy); } } editText.measure( MeasureUtil.getMeasureSpec(width, widthMode), MeasureUtil.getMeasureSpec(height, heightMode)); return YogaMeasureOutput.make(editText.getMeasuredWidth(), editText.getMeasuredHeight()); }
protected static Spannable fromTextCSSNode(ReactTextShadowNode textCSSNode) { SpannableStringBuilder sb = new SpannableStringBuilder(); // TODO(5837930): Investigate whether it's worth optimizing this part and do it if so // The {@link SpannableStringBuilder} implementation require setSpan operation to be called // up-to-bottom, otherwise all the spannables that are withing the region for which one may set // a new spannable will be wiped out List<SetSpanOperation> ops = new ArrayList<>(); buildSpannedFromTextCSSNode(textCSSNode, sb, ops); if (textCSSNode.mFontSize == UNSET) { sb.setSpan( new AbsoluteSizeSpan(textCSSNode.mAllowFontScaling ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : (int) Math.ceil(PixelUtil.toPixelFromDIP(ViewDefaults.FONT_SIZE_SP))), 0, sb.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } textCSSNode.mContainsImages = false; textCSSNode.mHeightOfTallestInlineImage = Float.NaN; // While setting the Spans on the final text, we also check whether any of them are images for (int i = ops.size() - 1; i >= 0; i--) { SetSpanOperation op = ops.get(i); if (op.what instanceof TextInlineImageSpan) { int height = ((TextInlineImageSpan)op.what).getHeight(); textCSSNode.mContainsImages = true; if (Float.isNaN(textCSSNode.mHeightOfTallestInlineImage) || height > textCSSNode.mHeightOfTallestInlineImage) { textCSSNode.mHeightOfTallestInlineImage = height; } } op.execute(sb); } return sb; }
@Override public long measure( YogaNodeAPI node, float width, YogaMeasureMode widthMode, float height, YogaMeasureMode heightMode) { // measure() should never be called before setThemedContext() EditText editText = Assertions.assertNotNull(mEditText); editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, mFontSize == UNSET ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : mFontSize); if (mNumberOfLines != UNSET) { editText.setLines(mNumberOfLines); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (editText.getBreakStrategy() != mTextBreakStrategy) { editText.setBreakStrategy(mTextBreakStrategy); } } editText.measure( MeasureUtil.getMeasureSpec(width, widthMode), MeasureUtil.getMeasureSpec(height, heightMode)); return YogaMeasureOutput.make(editText.getMeasuredWidth(), editText.getMeasuredHeight()); }
@Override public ReactEditText createViewInstance(ThemedReactContext context) { ReactEditText editText = new ReactEditText(context); int inputType = editText.getInputType(); editText.setInputType(inputType & (~InputType.TYPE_TEXT_FLAG_MULTI_LINE)); editText.setImeOptions(EditorInfo.IME_ACTION_DONE); editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP))); return editText; }
protected static Spannable fromTextCSSNode(ReactTextShadowNode textCSSNode) { SpannableStringBuilder sb = new SpannableStringBuilder(); // TODO(5837930): Investigate whether it's worth optimizing this part and do it if so // The {@link SpannableStringBuilder} implementation require setSpan operation to be called // up-to-bottom, otherwise all the spannables that are withing the region for which one may set // a new spannable will be wiped out List<SetSpanOperation> ops = new ArrayList<>(); buildSpannedFromTextCSSNode(textCSSNode, sb, ops); if (textCSSNode.mFontSize == UNSET) { sb.setSpan( new AbsoluteSizeSpan((int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP))), 0, sb.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } textCSSNode.mContainsImages = false; // While setting the Spans on the final text, we also check whether any of them are images for (int i = ops.size() - 1; i >= 0; i--) { SetSpanOperation op = ops.get(i); if (op.what instanceof TextInlineImageSpan) { textCSSNode.mContainsImages = true; } op.execute(sb); } return sb; }
@Override public void measure( CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode, MeasureOutput measureOutput) { // measure() should never be called before setThemedContext() EditText editText = Assertions.assertNotNull(mEditText); measureOutput.width = widthMode == CSSMeasureMode.UNDEFINED ? CSSConstants.UNDEFINED : width; editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, mFontSize == UNSET ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : mFontSize); mComputedPadding = spacingToFloatArray(getPadding()); editText.setPadding( (int) Math.ceil(getPadding().get(Spacing.LEFT)), (int) Math.ceil(getPadding().get(Spacing.TOP)), (int) Math.ceil(getPadding().get(Spacing.RIGHT)), (int) Math.ceil(getPadding().get(Spacing.BOTTOM))); if (mNumberOfLines != UNSET) { editText.setLines(mNumberOfLines); } editText.measure(0 /* unspecified */, 0 /* unspecified */); measureOutput.height = editText.getMeasuredHeight(); }
@Override public void measure( CSSNodeAPI node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode, MeasureOutput measureOutput) { // measure() should never be called before setThemedContext() EditText editText = Assertions.assertNotNull(mEditText); editText.setTextSize( TypedValue.COMPLEX_UNIT_PX, mFontSize == UNSET ? (int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP)) : mFontSize); mComputedPadding = new float[] { getPadding(Spacing.START), getPadding(Spacing.TOP), getPadding(Spacing.END), getPadding(Spacing.BOTTOM), }; editText.setPadding( (int) Math.floor(getPadding(Spacing.START)), (int) Math.floor(getPadding(Spacing.TOP)), (int) Math.floor(getPadding(Spacing.END)), (int) Math.floor(getPadding(Spacing.BOTTOM))); if (mNumberOfLines != UNSET) { editText.setLines(mNumberOfLines); } editText.measure( MeasureUtil.getMeasureSpec(width, widthMode), MeasureUtil.getMeasureSpec(height, heightMode)); measureOutput.width = editText.getMeasuredWidth(); measureOutput.height = editText.getMeasuredHeight(); }
protected static Spannable fromTextCSSNode(ReactTextShadowNode textCSSNode) { SpannableStringBuilder sb = new SpannableStringBuilder(); // TODO(5837930): Investigate whether it's worth optimizing this part and do it if so // The {@link SpannableStringBuilder} implementation require setSpan operation to be called // up-to-bottom, otherwise all the spannables that are withing the region for which one may set // a new spannable will be wiped out List<SetSpanOperation> ops = new ArrayList<>(); buildSpannedFromTextCSSNode(textCSSNode, sb, ops); if (textCSSNode.mFontSize == UNSET) { sb.setSpan( new AbsoluteSizeSpan((int) Math.ceil(PixelUtil.toPixelFromSP(ViewDefaults.FONT_SIZE_SP))), 0, sb.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } textCSSNode.mContainsImages = false; textCSSNode.mHeightOfTallestInlineImage = Float.NaN; // While setting the Spans on the final text, we also check whether any of them are images for (int i = ops.size() - 1; i >= 0; i--) { SetSpanOperation op = ops.get(i); if (op.what instanceof TextInlineImageSpan) { int height = ((TextInlineImageSpan)op.what).getHeight(); textCSSNode.mContainsImages = true; if (Float.isNaN(textCSSNode.mHeightOfTallestInlineImage) || height > textCSSNode.mHeightOfTallestInlineImage) { textCSSNode.mHeightOfTallestInlineImage = height; } } op.execute(sb); } return sb; }
@Override protected int getDefaultFontSize() { // top-level <Text /> should always specify font size. return fontSizeFromSp(ViewDefaults.FONT_SIZE_SP); }
@ReactProp(name = ViewProps.FONT_SIZE, defaultFloat = ViewDefaults.FONT_SIZE_SP) public void setFontSize(ReactEditText view, float fontSize) { view.setTextSize( TypedValue.COMPLEX_UNIT_PX, (int) Math.ceil(PixelUtil.toPixelFromSP(fontSize))); }
public void setNumberOfLines(int numberOfLines) { mNumberOfLines = numberOfLines == 0 ? ViewDefaults.NUMBER_OF_LINES : numberOfLines; setSingleLine(mNumberOfLines == 1); setMaxLines(mNumberOfLines); }
public void updateView() { @Nullable TextUtils.TruncateAt ellipsizeLocation = mNumberOfLines == ViewDefaults.NUMBER_OF_LINES ? null : mEllipsizeLocation; setEllipsize(ellipsizeLocation); }
@ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = ViewDefaults.NUMBER_OF_LINES) public void setNumberOfLines(ReactTextView view, int numberOfLines) { view.setNumberOfLines(numberOfLines); }
@ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = ViewDefaults.NUMBER_OF_LINES) public void setNumberOfLines(ReactTextView view, int numberOfLines) { view.setMaxLines(numberOfLines); view.setEllipsize(TextUtils.TruncateAt.END); }