敞开成长之旅!这是我参与「日新计划 12 月更文应战」的第4天,点击查看活动概况
跑马灯被运用在许多范畴, 例如商场的电子条幅、大楼的宣传广告位、地铁的广告位.不过毫无疑问的是它们都是为了解决文字过长的问题而应景给出的一种解决方案.
今天咱们来说一下flutter 怎么经过制作来完成跑马灯效果! 等不及想看源码的兄弟们,请走这儿:github.com/weniner/flu…
分析完成
咱们都知道跑马灯是不停的往前跑. 在给定的区域里,假如是最小的制作区域,咱们也至少制作出它左边刚出头,右边刚出尾的一切子项.一起咱们也需求一个东西来驱动它去前行.
一起,文字也会有许多情况. 它或许很短,也或许和给定的的区域持平,也或许远超咱们给定的区域. 在这种情况下,咱们应该首先获取文字的宽度.然后确认每秒它会移动多少.并且还需求一个驱动器来驱动它去做这些改变.
丈量文字
假如大家写过Flutter, 必定用过Text Widget. 既然Text Widget 能够依据文字大小来展示,阐明Flutter中是有一个api能够丈量文字长宽的.这儿直接给出答案:
// 咱们最终制作的文字
final String kText = 'Flutter 文字特效之跑马灯';
{
// 需求被丈量的文字 Widget
TextSpan measureText =
TextSpan(text: kText, style: const TextStyle(color: Colors.black));
TextPainter _painter = TextPainter(
text: measureText,
textDirection: TextDirection.ltr,
// 这儿界说最大为1行
maxLines: 1,
// 这儿给定文字制作的约束最小为0.0, 最大不限制.然后获取真实的文字宽高
)..layout(minWidth: 0.0, maxWidth: double.infinity);
}
其间,TextPainter便包含了咱们需求的文字宽高.咱们创立一个目标去保存这个信息,方便 后面去制作.
// 这儿继承里ChangeNotifier, 能够让咱们以最小的价值刷新界面
class _TextInfo extends ChangeNotifier {
// 制作时最前面的文字偏移
double head = 0.0;
double width;
double margin;
_TextInfo(this.width, this.margin);
// speed是咱们界说的偏移速度,
// 这儿与咱们的偏移量息息相关
void update(double speed) {
// 首先先让偏移量自减
head -= speed;
// 假如超过了文字大小和间距的总长度,阐明当时的文字已经超出了屏幕.
// 咱们应该用紧接着下一条数据的偏移量赋值.
if (head < -width - margin) {
head += width + margin;
}
notifyListeners();
}
}
动画为媒
文字丈量完后, 咱们还需求一个能够驱动文字移动的驱动器. 这儿你能够经过ticker自己完成一个驱动. 咱们为了简单化考虑, 没错~ 咱们又要请出咱们的好兄弟AnimationController重出江湖了
实际上这儿运用不了太多AnimationController的参数,咱们仅有需求在乎的便是Duration, 也便是时间越短.咱们将跑的越快.时间越长,跑的越慢.能够说是反比关系.
{
AnimationController _scrollController =
AnimationController(vsync: this, duration: const Duration(seconds:1));
}
最终制作
万事俱备,只欠东风. 像一个方程, 咱们一切的未知数都有了解. 只剩下最后求y了. 这儿咱们经过CustomPainter来制作文字. 咱们之前经过创立自己的类保存了文字信息,一起让它继承了ChangeNotifier便是为了今朝.
_RevolvingLanternPainter(
this.painter,
this.textInfo,
) : super(repaint: textInfo);
咱们将CustomPainter的repaint参数赋值成咱们自己界说的类. 每次咱们update() 都会通知界面来刷新,然后不会影响其他界面, 只影响当时的制作画布. 然后, 咱们就能够去真实的制作啦~ 这儿咱们仅有需求做的,便是给一个值x记录下一切文字的偏移量. 假如偏移量大于当时的界面. 阐明它不在界面上, 也就不用制作啦!
@override
void paint(Canvas canvas, Size size) {
double x = textInfo.head;
while (x < size.width) {
painter.paint(canvas, Offset(x, 0.0));
x += textInfo.width + textInfo.margin;
}
}
经过这种方法, 咱们完成了跑马灯文字的制作~~
源码
github.com/weniner/flu…
结语
这儿是WeninerIo, 期望这次的跑马灯教程能够给你带来一丝丝感悟. 假如你想看到更有意思的文字效果或者其他动画效果, 无妨谈论区留言 + 关注.期待下一次更好的相遇.