Android+Flutter实现文字跑马灯特效
作者:WeninerIo 发布时间:2022-11-24 05:57:58
跑马灯被运用在很多领域, 例如商场的电子条幅、大楼的宣传广告位、地铁的广告位.不过毫无疑问的是它们都是为了解决文字过长的问题而应景给出的一种解决方案.
今天我们来说一下flutter 怎么通过绘制来实现跑马灯效果! 等不及想看源码的兄弟们,请走这里:https://github.com/weniner/flutter_demo/blob/main/lib/text_effects/widget/marquee_effect.dart
分析实现
我们都知道跑马灯是不停的往前跑. 在给定的区域里,如果是最小的绘制区域,我们也至少绘制出它左边刚出头,右边刚出尾的所有子项.同时我们也需要一个东西来驱动它去前行.
同时,文字也会有很多情况.
它可能很短,也可能和给定的的区域相等,也可能远超我们给定的区域. 在这种情况下,我们应该首先获取文字的宽度.然后确定每秒它会移动多少.并且还需要一个驱动器来驱动它去做这些变化.
测量文字
如果大家写过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;
}
}
通过这种方法, 我们实现了跑马灯文字的绘制~~
源码:https://github.com/weniner/flutter_demo/blob/main/lib/text_effects/widget/marquee_effect.dart
来源:https://juejin.cn/post/7169502001162616868
猜你喜欢
- 本文实例讲述了C#控制台进行文件读写的方法。分享给大家供大家参考。具体如下:C#控制台进行文件写入:using System;using S
- 今天传图片,用的base64字符串,POST方法,前端传送的时候总是莫名其妙的崩溃,去网上搜了半天,以为是文件大小被限制了,但是我这个是字符
- Long end,long num,File file,String charset4个参数说明end 相当于坐标 ,tail 向上的起点,
- 简介本文用示例介绍SpringBoot如何解决BigDecimal传到前端后精度丢失问题。问题描述实例Controllerpackage c
- 一、准备工作和传统 CRUD 一样,实现对员工信息的增删改查。①搭建环境添加相关依赖web.xmlspringmvc.xml②准备实体类pu
- 不可变对象不可变(immutable): 即对象一旦被创建初始化后,它们的值就不能被改变,之后的每次改变都会产生一个新对象。var str=
- 一般有点开发经验的朋友都能实现这样的功能,只不过是效率上的问题。我们一般在面对这样的问题时,总会平铺直序的联想到,先生成一个数组,然后在一个
- 英文意思随机数可以做什么?生成一些随机的数字用途非常的广泛, 例如随机抽取数据库的一条记录,把生成的数字给变量,某一个时间点执行一些代码,随
- 打开idea项目后部分目录下出现橙色的时钟标志(如下):可以看到所有的java文件都显示了后缀名.java,文件的图标都变成了橙色的原因项目
- 却被编译器提示说:警告 1“System.Configuration.ConfigurationSettings.AppSettings”已
- JNI中的java接口使用项目需求,需要在c++函数中监听相应的状态,并在java端进行一些列的处理。这个需要在JNI中写一个subscri
- Android 调用发送短信的方 * 能:调用发送短信功能 1 、 权限 <uses-permission android:name=&
- 前言在工作中经常遇到C#数组、ArrayList、List、Dictionary存取数据,但是该选择哪种类型进行存储数据,对于初学者的我一直
- 本文内容介绍通过Java程序在Excel表格中根据数据来创建透视表。环境准备需要使用Excel类库工具—Free Spire.XLS for
- 题目一 解法/** * Definition for a binary tree node. * public class Tre
- 一.前言Unity3D是如今最火爆的游戏开发引擎,它可以让我们能轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型的互动内容。它支持2
- 这篇文章主要介绍了如何通过Java实现时间轴过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- 本文实例讲述了Java抽象类和抽象方法定义与用法。分享给大家供大家参考,具体如下:一、Java抽象类参考资料:Java抽象类 详解1、抽象类
- 有时我们会使用@Value自动注入,同时也存在注入到集合、数组等复杂类型的场景。这都是方便写 bug 的场景。1 @Value未注入预期值在
- 引言C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就具体看