Farcaller
Farcaller

Reputation: 3070

How to ignore Transformed WidgetSpan's text width when laying out the lines in RichText?

I want to move part of the text within RichText to occupy the place roughly above the previous word. I figured that the best option for that is to have the following hierarchy:

RichText
|
- TextSpan
- WidgetSpan
| |
| - Text
- TextSpan

with code like this:

RichText(
  text: TextSpan(
    style: TextStyle(
      color: Color(0xff696d77),
      fontSize: 30,
    ),
    children: [
      TextSpan(
        text: "before",
        style: const TextStyle(color: Color(0xff6e9ab1)),
      ),
      WidgetSpan(
        child: Transform.translate(
          offset: const Offset(-10, -20),
          child: const Text(
            "above",
            style: TextStyle(fontSize: 30, color: Colors.red),
          ),
        ),
      ),
      TextSpan(text: ' '),
      TextSpan(
        text: "after",
      ),
    ]
  )
)

This works almost perfect in re. translation:

enter image description here

but there's a bunch of white space between before and after the size of above. How do I get rid of it?

What I want to have:

enter image description here

Upvotes: 1

Views: 197

Answers (1)

Farcaller
Farcaller

Reputation: 3070

Actually it was much easier than expected. All it takes is to extend the WidgetSpan and not report the child width during the build:

class _UnsizedWidgetSpan extends WidgetSpan {
  _UnsizedWidgetSpan({required super.child});

  @override
  void build(ui.ParagraphBuilder builder,
      {double textScaleFactor = 1.0, List<PlaceholderDimensions>? dimensions}) {
    assert(debugAssertIsValid());
    assert(dimensions != null);
    final bool hasStyle = style != null;
    if (hasStyle) {
      builder.pushStyle(style!.getTextStyle(textScaleFactor: textScaleFactor));
    }
    assert(builder.placeholderCount < dimensions!.length);
    final PlaceholderDimensions currentDimensions =
        dimensions![builder.placeholderCount];
    builder.addPlaceholder(
      0,  // <-- do not report the width
      currentDimensions.size.height,
      alignment,
      scale: textScaleFactor,
      baseline: currentDimensions.baseline,
      baselineOffset: currentDimensions.baselineOffset,
    );
    if (hasStyle) {
      builder.pop();
    }
  }
}

Upvotes: 1

Related Questions