How can I make my stroke text compatible with overflow?

Viewed 262

I have the following text

// Flutter imports:
import 'package:flutter/material.dart';

@immutable
class StrokeText extends StatelessWidget {
  final String text;
  final Color color;
  final Color strokeColor;
  final double strokeWidth;
  final TextAlign? textAlign;
  final TextStyle? style;
  final TextOverflow? overflow;

  const StrokeText(
    this.text, {
    Key? key,
    this.color = Colors.white,
    this.strokeColor = Colors.black,
    this.strokeWidth = 1,
    this.textAlign,
    this.style,
    this.overflow,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Text(
          text,
          overflow: overflow,
          textAlign: textAlign,
          style: TextStyle(
            fontSize: style?.fontSize,
            fontWeight: style?.fontWeight,
            fontFamily: style?.fontFamily,
            height: style?.height,
            wordSpacing: style?.wordSpacing,
            overflow: overflow,
            foreground: Paint()
              ..strokeWidth = strokeWidth
              ..color = strokeColor
              ..style = PaintingStyle.stroke,
          ),
        ),
        Text(
          text,
          overflow: overflow,
          textAlign: textAlign,
          style: TextStyle(
            fontSize: style?.fontSize,
            fontWeight: style?.fontWeight,
            fontFamily: style?.fontFamily,
            height: style?.height,
            wordSpacing: style?.wordSpacing,
            overflow: overflow,
            foreground: Paint()..color = color,
          ),
        ),
      ],
    );
  }
}

But when it overflows, it the stoke seems to be cut off in certain parts

enter image description here

Where it normally show like this without overflow, which looks good

enter image description here

Example:

void main() {
  runApp(
    const MaterialApp(
      home: TestPage(),
    ),
  );
}

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          padding: const EdgeInsets.all(8.0),
          width: 500,
          height: 500,
          color: Colors.red,
          child: const Center(
            child: StrokeText(
              'ViQAQjlJXlaLeJMusUTNWAdjAkeTzneqAEbbIwCV',
              overflow: TextOverflow.ellipsis,
              strokeWidth: 4.0,
              style: TextStyle(
                fontSize: 30,
                fontWeight: FontWeight.w700,
                fontFamily: 'DePixel',
              ),
            ),
          ),
        ),
      ),
    );
  }
}
5 Answers

If you are giving height to your style then please remove it as of now and check without height because height is causing issue here.

And if still not working as you want then provide me code where you have used that StrokeText widget.

Is issue is the renderbox of stack is rendered only till the area of the text. You can wrap the stack in StrokeText class with a container and add a margin

return Container(
margin : EdgeInsets.all(strokeWidth),
 child: Stack(
 )
)

try this

import 'package:flutter/material.dart';
import 'package:untitled/stroke_text.dart';

void main() {
  runApp(
    const MaterialApp(
      home: TestPage(),
    ),
  );
}

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          margin: const EdgeInsets.all(8.0),
          padding: const EdgeInsets.all(8.0),
          width: 500,
          height: 500,
          color: Colors.red,
          child: const Center(
            child: StrokeText(
              'ViQAQjlJXlaLeJMusUTNWAdjAkeTzneqAEbbIwCV',
              overflow: TextOverflow.ellipsis,
              style: TextStyle(
                fontSize: 30,
                fontWeight: FontWeight.w700,
                fontFamily: 'DePixel',
              ),
            ),
          ),
        ),
      ),
    );
  }
}
import 'package:flutter/material.dart';

void main() => runApp(
  MaterialApp(
    home: Scaffold(
      body: Center(
        child: SizedBox(
          width: 100,
          child: OutlinedText(
              text: Text('Outlined Text asa asdasd asdasd sa', 
                      style: TextStyle(
                  fontSize: 30,
                       
                  fontWeight: FontWeight.w700,
                  fontFamily: 'DePixel',
                        color: Colors.white,
                        letterSpacing: -0.5
                ),
                         overflow: TextOverflow.ellipsis,
                         maxLines: 1,
                      ),
              strokes: [
                  OutlinedTextStroke(
                      color: Colors.black, 
                      width: 3
                  ),
              ],
          ),
        )
      )
    )
  )
);

class OutlinedTextStroke {
  final Color? color;
  final double? width;

  OutlinedTextStroke({this.color, this.width});
}

class OutlinedText extends StatelessWidget {
  final Text? text;
  final List<OutlinedTextStroke>? strokes;

  const OutlinedText({Key? key, this.text, this.strokes}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final children = <Widget>[];
    final list = strokes ?? [];
    double widthSum = 0;
    for (var i = 0; i < list.length; i++) {
      widthSum += list[i].width ?? 0;
      children.add(Text(text?.data ?? '',
          textAlign: text?.textAlign,
                        maxLines: text?.maxLines,
                        overflow: text?.overflow,
          style: (text?.style ?? TextStyle()).copyWith(
              foreground: Paint()
                ..style = PaintingStyle.stroke
                ..strokeWidth = widthSum
                ..color = list[i].color ?? Colors.transparent)));
    }

    return Stack(
      children: [...children.reversed, text ?? SizedBox.shrink()],
    );
  }
}

Try wrapping the widget with SizedBox

Related