Skip to content

Commit f653a87

Browse files
committed
Rebuild the TextView Layout before drawing text effects on Android
ReactTextView.onDraw paints CanvasEffectSpans (underline, strikethrough) only when getLayout() is non-null. TextView drops its Layout in setText and rebuilds it in onMeasure, and Fabric measures a view only when its frame changed, so a text state update that keeps the frame (a decoration or color change on a text of the same size) reaches onDraw with no Layout and the decorations are skipped until something else re-measures the view. Rebuild the Layout at the current size before painting; TextView.onDraw would build one for the plain text anyway.
1 parent 2a2ccaa commit f653a87

1 file changed

Lines changed: 9 additions & 0 deletions

File tree

  • packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,15 @@ protected void onDraw(Canvas canvas) {
260260

261261
if (spanned != null) {
262262
Layout layout = getLayout();
263+
if (layout == null && getWidth() > 0 && getHeight() > 0) {
264+
// setText drops the Layout and Fabric re-measures only on a frame change, so a text
265+
// update that kept the frame reaches onDraw without one and the effects below would be
266+
// skipped. Rebuild it here; TextView.onDraw would build one for the text anyway.
267+
measure(
268+
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
269+
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
270+
layout = getLayout();
271+
}
263272
if (layout != null) {
264273
CanvasEffectSpan[] drawSpans =
265274
spanned.getSpans(0, spanned.length(), CanvasEffectSpan.class);

0 commit comments

Comments
 (0)