DEV Community

Ge Ji
Ge Ji

Posted on

Flutter Lesson 5:Text and Styles

Text is one of the most basic and important elements in any application. In Flutter, text display and style control are very flexible, capable of meeting various complex UI requirements. This lesson will detailedly introduce core components and style control methods related to text in Flutter, helping you master various text display techniques.

I. Detailed Explanation of Text Widget Properties

The Text widget is the basic component for displaying text in Flutter, providing rich properties to control the appearance and behavior of text.

Basic Properties

Text(
  "Hello Flutter", // Text content to display
  style: TextStyle(...), // Text style
  textAlign: TextAlign.center, // Text alignment
  textDirection: TextDirection.ltr, // Text direction (left-to-right/right-to-left)
  softWrap: true, // Whether to wrap text automatically
  overflow: TextOverflow.ellipsis, // Text overflow handling
  maxLines: 2, // Maximum number of lines
  textScaleFactor: 1.0, // Text scaling factor
  semanticsLabel: "Hello Flutter", // Semantic label for accessibility
)
Enter fullscreen mode Exit fullscreen mode

Detailed Explanation of Common Properties

  1. textAlign - Text alignment
// Optional values
TextAlign.left      // Left alignment
TextAlign.right     // Right alignment
TextAlign.center    // Center alignment
TextAlign.justify   // Justified alignment
TextAlign.start     // Alignment at start of text direction
TextAlign.end       // Alignment at end of text direction
Enter fullscreen mode Exit fullscreen mode

2 . overflow - Text overflow handling

// Common values
TextOverflow.clip      // Clip overflowing content
TextOverflow.fade      // Fade out overflowing content
TextOverflow.ellipsis  // Show ellipsis (...) for overflow
TextOverflow.visible   // Allow content to overflow
Enter fullscreen mode Exit fullscreen mode

3 . softWrap - Automatic line wrapping control
- true (default): Text wraps when exceeding container width
- false: Text doesn't wrap, may cause overflow

4 . maxLines - Maximum line limit
- Set to null for no limit (default)
- Used with overflow property to control handling of text exceeding line limit


II. TextStyle for Style Control

TextStyle is the core class for controlling text appearance, with almost all text-related styles defined through it.

Common Style Properties

TextStyle(
  fontSize: 16.0, // Font size, default 14
  color: Colors.black87, // Text color
  fontWeight: FontWeight.w400, // Font weight
  fontStyle: FontStyle.normal, // Font style (normal/italic)
  letterSpacing: 0.5, // Letter spacing
  wordSpacing: 2.0, // Word spacing
  height: 1.5, // Line height, multiplier of font size
  backgroundColor: Colors.yellow, // Background color
  decoration: TextDecoration.none, // Text decoration (underline, etc.)
  decorationColor: Colors.red, // Decoration line color
  decorationStyle: TextDecorationStyle.solid, // Decoration line style
  fontFamily: "Roboto", // Font family
  shadows: [ // Text shadows
    Shadow(
      color: Colors.grey,
      offset: Offset(1, 1),
      blurRadius: 2,
    )
  ],
)
Enter fullscreen mode Exit fullscreen mode

Font Weight (fontWeight)

FontWeight defines the thickness of text, with common values including:

  • FontWeight.w100 - Thinest
  • FontWeight.w300 - Light
  • FontWeight.w400 - Normal (default)
  • FontWeight.w500 - Medium
  • FontWeight.w700 - Bold
  • FontWeight.w900 - Black
  • Shortcut: FontWeight.bold is equivalent to FontWeight.w700

Text Decoration (decoration)

You can add various decorative lines to text:

TextDecoration.none        // No decoration
TextDecoration.underline   // Underline
TextDecoration.overline    // Overline
TextDecoration.lineThrough // Line through
Enter fullscreen mode Exit fullscreen mode

Decoration line styles (decorationStyle):

TextDecorationStyle.solid   // Solid line (default)
TextDecorationStyle.dashed  // Dashed line
TextDecorationStyle.dotted  // Dotted line
TextDecorationStyle.double  // Double line
TextDecorationStyle.wavy    // Wavy line
Enter fullscreen mode Exit fullscreen mode

III. DefaultTextStyle for Style Reuse

In actual development, we often need to maintain consistent text styles across different parts of an application. DefaultTextStyle allows us to set default text styles for an entire subtree of widgets, enabling style reuse.

Basic Usage

DefaultTextStyle(
  // Set default text style
  style: const TextStyle(
    color: Colors.grey,
    fontSize: 14,
    fontFamily: 'sans-serif',
  ),
  // Text alignment
  textAlign: TextAlign.start,
  // Maximum lines
  maxLines: 2,
  // Overflow handling
  overflow: TextOverflow.ellipsis,
  // Child widget tree
  child: Column(
    children: const [
      Text("This text uses the default style"),
      Text("This text also uses the default style"),
      // Can override default style
      Text(
        "This text uses a custom style",
        style: TextStyle(
          color: Colors.blue,
          fontSize: 16,
        ),
      ),
    ],
  ),
)
Enter fullscreen mode Exit fullscreen mode

Practical Application Scenarios

DefaultTextStyle is particularly suitable for components containing multiple text elements such as lists and cards. It allows setting base styles uniformly while enabling individual styling where special styles are needed, ensuring consistency while maintaining flexibility.


IV. Rich Text with RichText and TextSpan

When needing multiple different styles within a single text passage, the Text widget is insufficient. We need to use RichText with TextSpan to achieve rich text effects.

Basic Usage of RichText

RichText(
  text: TextSpan(
    // Base style, child TextSpans inherit this
    style: const TextStyle(
      color: Colors.black87,
      fontSize: 16,
    ),
    children: [
      const TextSpan(text: "This is a section of"),
      TextSpan(
        text: "red bold text",
        style: const TextStyle(
          color: Colors.red,
          fontWeight: FontWeight.bold,
        ),
        // Can add tap event
        recognizer: TapGestureRecognizer()
          ..onTap = () {
            print("Tapped red bold text");
          },
      ),
      const TextSpan(text: "where this part"),
      TextSpan(
        text: "has an underline",
        style: const TextStyle(
          decoration: TextDecoration.underline,
          color: Colors.blue,
        ),
      ),
      const TextSpan(text: "."),
    ],
  ),
  // Text alignment
  textAlign: TextAlign.center,
)
Enter fullscreen mode Exit fullscreen mode

Nested TextSpan Usage

TextSpan can be nested for more complex text structures:

RichText(
  text: TextSpan(
    style: const TextStyle(color: Colors.black, fontSize: 16),
    children: [
      const TextSpan(text: "User Agreement:\n\n"),
      TextSpan(
        children: [
          const TextSpan(text: "1. "),
          const TextSpan(
            text: "This agreement",
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          const TextSpan(text: "applies to all users.\n"),
        ],
      ),
      TextSpan(
        children: [
          const TextSpan(text: "2. Users must comply with the"),
          TextSpan(
            text: "terms of service",
            style: const TextStyle(color: Colors.blue),
            recognizer: TapGestureRecognizer()
              ..onTap = () {
                // Navigate to terms of service page
              },
          ),
          const TextSpan(text: "and related regulations."),
        ],
      ),
    ],
  ),
)
Enter fullscreen mode Exit fullscreen mode

Practical Application Scenarios

Rich text is commonly used for:

  • Text paragraphs with different styles (e.g., agreement text)
  • Text with highlighted sections (e.g., search results)
  • Clickable text links (e.g., privacy policy links)
  • Mixed icons and text (via WidgetSpan)

WidgetSpan for Mixing Widgets and Text

WidgetSpan allows inserting other widgets within text for text-image mixing:

RichText(
  text: TextSpan(
    style: const TextStyle(color: Colors.black, fontSize: 16),
    children: [
      const TextSpan(text: "Your points: "),
      WidgetSpan(
        child: Icon(Icons.star, color: Colors.yellow[700], size: 18),
      ),
      const TextSpan(
        text: " 1250",
        style: TextStyle(color: Colors.orange, fontWeight: FontWeight.bold),
      ),
    ],
  ),
)
Enter fullscreen mode Exit fullscreen mode

V. Font Import and Custom Fonts

Flutter supports using custom fonts to give your app a unique text style. Using custom fonts requires the following steps:

Step 1: Prepare Font Files

  1. Create a fonts folder in the project root directory (if it doesn't exist)
  2. Place font files (usually .ttf or .otf format) in this folder
  3. It's recommended to create subfolders for different weights/styles to keep the structure clear:
fonts/
  OpenSans/
    OpenSans-Regular.ttf
    OpenSans-Bold.ttf
    OpenSans-Italic.ttf
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Fonts in pubspec.yaml

Open the pubspec.yaml file in the project root directory and add font configurations:

flutter:
  fonts:
    - family: OpenSans  # Font family name, used in code
      fonts:
        - asset: fonts/OpenSans/OpenSans-Regular.ttf  # Regular font
        - asset: fonts/OpenSans/OpenSans-Bold.ttf
          weight: 700  # Bold weight
        - asset: fonts/OpenSans/OpenSans-Italic.ttf
          style: italic  # Italic style
Enter fullscreen mode Exit fullscreen mode

Configuration explanation:

  • family: Font family name, used in TextStyle's fontFamily property
  • asset: Path to font file relative to project root
  • weight: Optional, specifies font weight (100-900)
  • style: Optional, specifies style (normal/italic)

After configuration, run flutter pub get to make the configuration effective.

Step 3: Use Custom Fonts

Reference custom fonts in TextStyle through the fontFamily property:

Text(
  "Text using custom font",
  style: TextStyle(
    fontFamily: "OpenSans",  // Matches family in pubspec.yaml
    fontSize: 20,
  ),
)

// Using bold variant
Text(
  "Bold text with custom font",
  style: TextStyle(
    fontFamily: "OpenSans",
    fontWeight: FontWeight.w700,  // Matches weight in configuration
    fontSize: 20,
  ),
)

// Using italic variant
Text(
  "Italic text with custom font",
  style: TextStyle(
    fontFamily: "OpenSans",
    fontStyle: FontStyle.italic,  // Matches style in configuration
    fontSize: 20,
  ),
)
Enter fullscreen mode Exit fullscreen mode

Step 4: Set Global Default Font

To use a custom font throughout the entire application, configure it through ThemeData:

MaterialApp(
  title: 'Custom Font Example',
  theme: ThemeData(
    // Set global font
    fontFamily: 'OpenSans',
    // Other theme configurations...
  ),
  home: const MyHomePage(),
)
Enter fullscreen mode Exit fullscreen mode

VI. Practical Text Techniques

1. Responsive Font Sizes

Automatically adjust font size based on different screen sizes:

// Use MediaQuery to get screen information
Text(
  "Responsive font",
  style: TextStyle(
    fontSize: MediaQuery.of(context).size.width * 0.05, // 5% of screen width
  ),
)

// Use FittedBox to automatically fit container
Container(
  width: 100,
  child: FittedBox(
    fit: BoxFit.scaleDown,
    child: Text("This text will automatically shrink to fit container width"),
  ),
)
Enter fullscreen mode Exit fullscreen mode

2. Text Spacing and Line Height Adjustment

Text(
  "Example text with adjusted line height and letter spacing. "
  "This is the second line to demonstrate line height effect.",
  style: TextStyle(
    fontSize: 16,
    letterSpacing: 1.2, // Letter spacing
    wordSpacing: 3.0, // Word spacing
    height: 1.8, // Line height, multiplier of font size
  ),
  textAlign: TextAlign.justify,
)
Enter fullscreen mode Exit fullscreen mode

3. Text Selection and Copying

By default, text in the Text widget is not selectable. To enable text selection, use SelectableText:

SelectableText(
  "This text can be selected and copied. "
  "Long press to show context menu for copy operations.",
  style: const TextStyle(fontSize: 16),
  cursorColor: Colors.blue, // Cursor color
  selectionColor: Colors.blue.withOpacity(0.2), // Selected text background color
  onSelectionChanged: (selection, cause) {
    // Callback when selection state changes
    print("Selected text: ${selection.textInside('This text can be selected and copied. Long press to show context menu for copy operations.')}");
  },
)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)