Skip to content

Commit 7affdde

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 a9307d8 commit 7affdde

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
@@ -257,6 +257,15 @@ protected void onDraw(Canvas canvas) {
257257

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

0 commit comments

Comments
 (0)