go to index

Flutter 字体描边效果

read time 2 min read
flutter
dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter 字体描边效果',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter 字体描边效果'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Column(
        children: [
          HollowText(
            strokeColor: Colors.black,
            strokeWidth: 2,
            child: const Text(
              'The quick brown fox jumps over the lazy dog.',
              style: TextStyle(
                fontSize: 40,
                color: Colors.red,
              ),
            ),
          ),
          HollowText(
            strokeColor: Colors.black,
            strokeWidth: 2,
            child: const Text(
              'THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.',
              style: TextStyle(
                fontSize: 40,
                color: Colors.red,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class HollowText extends StatelessWidget {
  HollowText({
    super.key,
    required this.child,
    required this.strokeWidth,
    required this.strokeColor,
  }) : assert(child.style != null, "style 不能为 null");

  final Text child;
  final double strokeWidth;
  final Color strokeColor;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Text(
          child.data!,
          style: child.style!.copyWith(
            foreground: Paint()
              ..style = PaintingStyle.stroke
              ..strokeCap = StrokeCap.round
              ..strokeJoin = StrokeJoin.round
              ..strokeWidth = strokeWidth
              ..color = strokeColor,
          ),
          maxLines: child.maxLines,
          overflow: child.overflow,
          semanticsLabel: child.semanticsLabel,
          softWrap: child.softWrap,
          strutStyle: child.strutStyle,
          textAlign: child.textAlign,
          textDirection: child.textDirection,
          textScaler: child.textScaler,
        ),
        child
      ],
    );
  }
}