Skip to content

Instantly share code, notes, and snippets.

@rtybanana
Created October 1, 2021 22:08
Show Gist options
  • Save rtybanana/2b0639052cd5bfd701b8d892f2d1088b to your computer and use it in GitHub Desktop.
Save rtybanana/2b0639052cd5bfd701b8d892f2d1088b to your computer and use it in GitHub Desktop.
Marquee wrapper which only scrolls if the text is large enough
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:marquee/marquee.dart' as wrapped;
class Marquee extends StatelessWidget {
final String text;
final TextStyle? style;
final double? textScaleFactor;
final TextDirection textDirection;
final Axis scrollAxis;
final CrossAxisAlignment crossAxisAlignment;
final double blankSpace;
final double velocity;
final Duration startAfter;
final Duration pauseAfterRound;
final int? numberOfRounds;
final bool showFadingOnlyWhenScrolling;
final double fadingEdgeStartFraction;
final double fadingEdgeEndFraction;
final double startPadding;
final Duration accelerationDuration;
final Curve accelerationCurve;
final Duration decelerationDuration;
final Curve decelerationCurve;
final VoidCallback? onDone;
Marquee({
Key? key,
required this.text,
this.style,
this.textScaleFactor,
this.textDirection = TextDirection.ltr,
this.scrollAxis = Axis.horizontal,
this.crossAxisAlignment = CrossAxisAlignment.center,
this.blankSpace = 0.0,
this.velocity = 50.0,
this.startAfter = Duration.zero,
this.pauseAfterRound = Duration.zero,
this.showFadingOnlyWhenScrolling = true,
this.fadingEdgeStartFraction = 0.0,
this.fadingEdgeEndFraction = 0.0,
this.numberOfRounds,
this.startPadding = 0.0,
this.accelerationDuration = Duration.zero,
this.accelerationCurve = Curves.decelerate,
this.decelerationDuration = Duration.zero,
this.decelerationCurve = Curves.decelerate,
this.onDone,
});
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
var span = TextSpan(
text: text,
style: style,
);
var tp = TextPainter(
maxLines: 1,
textAlign: TextAlign.left,
textDirection: TextDirection.ltr,
text: span,
);
tp.layout(maxWidth: constraints.maxWidth);
if (tp.didExceedMaxLines) return Container(
height: tp.height,
width: constraints.maxWidth,
child: wrapped.Marquee(
text: text,
style: style,
textScaleFactor: textScaleFactor,
textDirection: textDirection,
scrollAxis: scrollAxis,
crossAxisAlignment: crossAxisAlignment,
blankSpace: blankSpace,
velocity: velocity,
startAfter: startAfter,
pauseAfterRound: pauseAfterRound,
numberOfRounds: numberOfRounds,
showFadingOnlyWhenScrolling: showFadingOnlyWhenScrolling,
fadingEdgeStartFraction: fadingEdgeStartFraction,
fadingEdgeEndFraction: fadingEdgeEndFraction,
startPadding: startPadding,
accelerationDuration: accelerationDuration,
accelerationCurve: accelerationCurve,
decelerationDuration: decelerationDuration,
decelerationCurve: decelerationCurve,
onDone: onDone,
),
);
else return Container(
width: constraints.maxWidth,
child: Text(
text,
style: style,
textAlign: TextAlign.left,
)
);
});
}
}
@cirediew
Copy link

cirediew commented Nov 8, 2021

I noticed it's not working well when text scaling is turned up in the device settings so I've added that like so:

  @override
  Widget build(BuildContext context) {
    final _textScaleFactor = textScaleFactor ?? MediaQuery.of(context).textScaleFactor; //<<<<<<
    return LayoutBuilder(
      builder: (context, constraints) {
        final span = TextSpan(
          text: text,
          style: style,
        );

        final tp = TextPainter(
          maxLines: 1,
          textAlign: TextAlign.left,
          textDirection: TextDirection.ltr,
          textScaleFactor: _textScaleFactor, //<<<<<<
          text: span,
        );

        tp.layout(maxWidth: constraints.maxWidth);

        if (tp.didExceedMaxLines) {
          return SizedBox(
            height: tp.height,
            width: constraints.maxWidth,
            child: wrapped.Marquee(
              text: text,
              style: style,
              textScaleFactor: _textScaleFactor, //<<<<<<

@thorizer
Copy link

can we also make the wrapper start scrolling only after a tap ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment