I am encouterring problem with my personal GradientText which is made to do not use ShaderMask.
Here the device I use:
I call it like that:
Column(
children: [
GradientText(
'Party Lopes',
const LinearGradient(
colors: <Color>[
Color.fromARGB(255, 227, 82, 0),
Color.fromARGB(255, 244, 176, 0)
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
style: TextStyle(
fontWeight: FontWeight.w500
),
),
],
)
And here the code of my Widget:
import 'package:flutter/material.dart';
class GradientText extends StatelessWidget {
final String text;
final TextStyle style;
final Gradient? gradient;
final int? maxLine;
const GradientText(
this.text,
{
@required this.gradient,
this.style = const TextStyle(),
this.maxLine = 1,
Key? key,
}
) : super(key: key);
@override
Widget build(BuildContext context) {
final TextPainter _painter = TextPainter(
maxLines: maxLine,
textDirection: TextDirection.rtl,
text: TextSpan(
text: text,
style: style
),
);
_painter.layout();
print(_painter.size);
return CustomPaint(
size: _painter.size,
painter: _GradientTextPainter(
text: text,
style: style,
gradient: gradient,
maxLine: maxLine
),
);
}
}
class _GradientTextPainter extends CustomPainter {
final Gradient? gradient;
final String? text;
final TextStyle? style;
final int? maxLine;
_GradientTextPainter({
Listenable? repaint,
@required this.text,
@required this.style,
@required this.gradient,
@required this.maxLine,
}) : super(repaint: repaint);
@override
void paint(Canvas canvas, Size size) {
final Paint _gradientShaderPaint = Paint()
..shader = gradient != null ?
gradient!.createShader(
Offset.zero & size
) :
null;
final TextPainter _textPainter = TextPainter(
maxLines: maxLine,
textDirection: TextDirection.ltr,
text: TextSpan(
text: text!,
style: TextStyle(
foreground: _gradientShaderPaint,
fontSize: style!.fontSize,
fontWeight: style!.fontWeight,
height: style!.height,
decoration: style!.decoration,
decorationColor: style!.decorationColor,
decorationStyle: style!.decorationStyle,
fontStyle: style!.fontStyle,
letterSpacing: style!.letterSpacing,
fontFamily: style!.fontFamily,
locale: style!.locale,
textBaseline: style!.textBaseline,
wordSpacing: style!.wordSpacing,
),
)
);
_textPainter.layout(
minWidth: 0,
maxWidth: size.width,
);
_textPainter.paint(
canvas,
Offset(
(size.width - _textPainter.width) / 2,
(size.height - _textPainter.height) / 2
)
);
}
@override
bool shouldRepaint(_GradientTextPainter oldDelegate) {
return gradient != oldDelegate.gradient || text != oldDelegate.text ||
style != oldDelegate.style;
}
}
And here it gives this result :
Whereas it should give this result:
So I don't understand why it doesn't display the entire text, and I don't understand why when I pass 'Party Lo' as a text parameter it displays it.
And also I don't understand why when I change the maxLines to 2 for example it place it under my first line whereas there is so much space already available
Can somebody please provide help fixing these problems ?
Here the result I am trying to have:
i simplified your _GradientTextPainter
a little bit and also added optional alignment
property to GradientText
- if incoming size constraints are not bounded (either width or height is not set) then it takes the minimum intrinsic size to draw itself, otherwise alignment
is used to align GradientText
within sized parent widget:
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class GradientText extends StatelessWidget {
final String text;
final TextStyle style;
final Gradient gradient;
final int maxLines;
final Alignment alignment;
final String ellipsis;
const GradientText(
this.text,
this.gradient,
{
this.style = const TextStyle(),
this.maxLines = 1,
this.alignment = Alignment.centerLeft,
this.ellipsis = '\u2026',
Key? key,
}
) : super(key: key);
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
final TextPainter textPainter = TextPainter(
maxLines: maxLines,
textDirection: TextDirection.ltr,
text: TextSpan(
text: text,
style: style,
),
ellipsis: ellipsis,
);
textPainter.layout(
maxWidth: constraints.maxWidth,
);
final bounded = constraints.hasBoundedHeight &&
constraints.hasBoundedWidth;
final size = bounded? constraints.biggest : textPainter.size;
// print('constraints.biggest: ${constraints.biggest},
// textPainter.size: ${textPainter.size}');
// print('incoming constraints are ${bounded? "" : "NOT "}bounded,
// using ${bounded? "constraint\'s" : "text"} size: $size');
return CustomPaint(
painter: _GradientTextPainter(
text: text,
style: style,
gradient: gradient,
textPainter: textPainter,
alignment: alignment,
),
size: size,
);
}
);
}
}
class _GradientTextPainter extends CustomPainter {
final Gradient gradient;
final String text;
final TextStyle style;
final TextPainter textPainter;
final Alignment alignment;
_GradientTextPainter({
Listenable? repaint,
required this.text,
required this.style,
required this.gradient,
required this.textPainter,
required this.alignment,
}) : super(repaint: repaint);
@override
void paint(Canvas canvas, Size size) {
final textSpanRect = alignment.inscribe(
textPainter.size,
Offset.zero & size
);
// print('=== $size * $alignment => $textSpanRect');
if (debugPaintSizeEnabled)
debugPaintPadding(canvas, textSpanRect, textSpanRect.deflate(2));
textPainter.text = TextSpan(
text: text,
style: style.copyWith(
foreground: Paint()..shader = gradient.createShader(textSpanRect),
),
);
textPainter.layout(
minWidth: 0,
maxWidth: size.width,
);
textPainter.paint(canvas, textSpanRect.topLeft);
}
@override
bool shouldRepaint(_GradientTextPainter oldDelegate) {
return gradient != oldDelegate.gradient || text != oldDelegate.text ||
style != oldDelegate.style;
}
}