What is RichText?
RichText is a widget that displays text with multiple styles. It uses a tree of TextSpan objects, each with its own style, and optionally WidgetSpan to embed widgets inline. This is the foundation for creating styled text, links, and even interactive elements within a text flow. Unlike Text, which applies a single style to the whole string, RichText gives you fine‑grained control over every part.
Basic RichText with TextSpan
The TextSpan tree builds the text. Each span can have its own style, and nested spans inherit the parent style unless overridden.
Inline Widgets with WidgetSpan
WidgetSpan allows you to embed any widget inside text. This is great for adding inline icons, buttons, or custom components.
Handling Tap Events (Links)
You can make parts of the text tappable by adding a TapGestureRecognizer to a TextSpan using recognizer. This is how you create clickable links without using GestureDetector.
Nested Styles and Inheritance
Styles cascade from parent to child. A child span can override inherited properties (like color or fontSize) or add new ones.
Text Selection and SelectionControls
RichText supports text selection out of the box if you set selectionColor and use SelectableText.rich instead. For selectable rich text, use SelectableText.rich which takes a TextSpan tree. You can also customize selection controls with SelectionControls.
Performance Considerations
- Use
constfor staticTextStyleobjects to avoid unnecessary rebuilds.
- Use
- For many spans, consider building the text with a loop and storing the spans in a list.
- Avoid creating new recognizers on every build; create them once and reuse.
- When using
WidgetSpan, ensure the embedded widgets are lightweight (e.g., small icons, not heavy animations).
- When using
Common Mistakes
- Forgetting to add
recognizertoTextSpan: Without it, the text won't respond to taps. Also remember to importflutter/gestures.dart.
- Forgetting to add
- Using
TextSpanwithout a root style: If you don't set a default style on the root, text may be invisible (no color).
- Using
- Creating recognizers inside the build method: This creates new instances on each rebuild, which can cause memory leaks and performance issues. Create them in
initStateor as constants.
- Creating recognizers inside the build method: This creates new instances on each rebuild, which can cause memory leaks and performance issues. Create them in
- Not handling overflow: RichText does not automatically wrap; use
softWrap: trueand a proper container width.
- Not handling overflow: RichText does not automatically wrap; use
- Mixing
RichTextwithSelectableText.richincorrectly:RichTextis not selectable; useSelectableText.richfor selectable text.
- Mixing
Best Practices
- Define a base
TextStylefor the rootTextSpanand override only what changes in children.
- Define a base
- For interactive spans, create recognizers as member variables and dispose them if necessary (e.g.,
TapGestureRecognizer).
- For interactive spans, create recognizers as member variables and dispose them if necessary (e.g.,
- Use
WidgetSpansparingly; if you need many inline widgets, consider using aWraporRowfor better performance.
- Use
- Always set
softWrap: trueandoverflow: TextOverflow.ellipsisto handle long text gracefully.
- Always set
Key Takeaways
RichTextdisplays text with multiple styles usingTextSpannodes.
TextSpancan havestyle,text,children, andrecognizerfor taps.
WidgetSpanallows embedding widgets inline (icons, buttons).
- Use
SelectableText.richfor selectable rich text.
- Use
- Style inheritance reduces code duplication.
- Manage recognizers carefully to avoid memory leaks.