flutter 文字从左到右轮播滚动,跑马灯

2023-11-03

参考

/// description_begin.
/// 跑马灯, 根据滚动方向可以分为 横向滚动 和 纵向滚动。
/// 此页实现的跑马灯是 横向滚动的。
/// description_end.
import 'dart:async';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key) {
    debugPrint('Track_MyApp');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('跑马灯'),
        ),
        //body占屏幕的大部分。
        body: _buildBody(),
      ),
    );
  }

  Widget _buildBody() {
    return Container(
        margin: const EdgeInsets.only(left: 15, top: 10, right: 15),
        padding: const EdgeInsets.only(left: 15, right: 15),
        height: 36,
        decoration: BoxDecoration(
          color: const Color(0xFFAAAAAA),
          borderRadius: BorderRadius.circular(15),
        ),
        child: Row(
          children: <Widget>[
            Container(
              margin: const EdgeInsets.only(right: 10),
              width: 15,
              height: 15,
              decoration: const BoxDecoration(
                color: Colors.blue,
              ),
            ),
            Expanded(
              child: MarqueeView(
                child: _buildText(
                    '手机用户155****0523借款成功 ( This text is to long to be shown in just one line. )'),
              ),
            ),
          ],
        ));
  }

  Widget _buildText(String txt) {
    return Text(
      txt,
      style: const TextStyle(
        fontSize: 13,
        color: Colors.white,
      ),
      maxLines: 1,
      overflow: TextOverflow.fade,
    );
  }
}

//

class MarqueeView extends StatefulWidget {
  final Duration pauseDuration, forwardDuration;
  final double scrollSpeed; //滚动速度(时间单位是秒)。
  final Widget child; //子视图。

  /// 注: 构造函数入参的默认值必须是常量。
  const MarqueeView(
      {Key? key,
      this.pauseDuration = const Duration(milliseconds: 100),
      this.forwardDuration = const Duration(milliseconds: 3000),
      this.scrollSpeed = 40.0,
      required this.child})
      : super(key: key);

  @override
  _MarqueeViewState createState() => _MarqueeViewState();
}

class _MarqueeViewState extends State<MarqueeView>
    with SingleTickerProviderStateMixin {
  bool _validFlag = true;
  double _boxWidth = 0;
  final ScrollController _controller = ScrollController();

  @override
  void dispose() {
    debugPrint('Track_MarqueeView_dispose');
    _validFlag = false;
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    scroll();
  }

  @override
  Widget build(BuildContext context) {
    /// 使用LayoutBuilder获取组件的大小。
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        _boxWidth = constraints.maxWidth;
        return SingleChildScrollView(
          // 禁止手动滑动。
          physics: const NeverScrollableScrollPhysics(),
          controller: _controller,
          scrollDirection: Axis.horizontal,
          child: Container(
            padding: EdgeInsets.symmetric(horizontal: _boxWidth),
            child: widget.child,
          ),
        );
      },
    );
  }

  void scroll() async {
    while (_validFlag) {
      debugPrint('Track_MarqueeView_scroll');
      await Future.delayed(widget.pauseDuration);
      if (_boxWidth <= 0) {
        continue;
      }
      _controller.jumpTo(0);
      // 两个方向: Curves.easeIn 和 Curves.easeOut 。
      await _controller.animateTo(_controller.position.maxScrollExtent,
          duration: Duration(
              seconds:
                  (_controller.position.maxScrollExtent / widget.scrollSpeed)
                      .floor()),
          curve: Curves.easeIn);
    }
  }
}

我自己的跑马灯需要用到多语言,需要用到html

import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';

import '../widget/marquee_view.dart';

class DirectText extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => DirectTextState();
}

class DirectTextState extends State<DirectText> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('跑马灯'),
        ),
        //body占屏幕的大部分。
        body: _buildBody(),
      ),
    );
  }

  Widget _buildBody() {
    return Column(
      children: [
        Container(alignment: Alignment.centerLeft,child: htmlText()),
        Container(
            margin: const EdgeInsets.only(left: 15, top: 10, right: 15),
            padding: const EdgeInsets.only(left: 15, right: 15),
            height: 36,
            decoration: BoxDecoration(
              color: const Color(0xFFAAAAAA),
              borderRadius: BorderRadius.circular(15),
            ),
            child: Row(
              children: <Widget>[
                Container(
                  margin: const EdgeInsets.only(right: 10),
                  width: 15,
                  height: 15,
                  decoration: const BoxDecoration(
                    color: Colors.blue,
                  ),
                ),
                Expanded(
                  child: MarqueeView(
                    child: Row(
                      children: [
                        htmlText(),
                        htmlText(),
                        htmlText(),
                        htmlText(),
                        htmlText(),
                        htmlText(),
                      ],
                    ),
                  ),
                ),
              ],
            )),
      ],
    );
  }

  String textData = """
<p > This <b>num</b> is some text</p>
""";

  Widget htmlText() {
    return Container(
      color: Colors.blue,
      child: Html(shrinkWrap: true, data: textData, style: {
        "html": Style(
            padding: EdgeInsets.all(0),
            margin: EdgeInsets.all(0),
            backgroundColor: Colors.grey,
            textAlign: TextAlign.center),
        "body": Style(padding: EdgeInsets.all(0), margin: EdgeInsets.all(0)),
        "p": Style(
            padding: EdgeInsets.all(0),
            margin: EdgeInsets.all(0),
            fontSize: FontSize.rem(1.02),
            color: const Color(0xFF373737),
            fontWeight: FontWeight.w400),
        "p > b": Style(
            padding: EdgeInsets.all(0),
            margin: EdgeInsets.all(0),
            fontSize: FontSize.rem(1.02),
            color: const Color(0xFF373737),
            fontWeight: FontWeight.w600)
      }),
    );
  }
}


import 'dart:async';
import 'package:flutter/material.dart';

class MarqueeView extends StatefulWidget {
  final Duration pauseDuration, forwardDuration;
  final double scrollSpeed; //滚动速度(时间单位是秒)。
  final Widget child; //子视图。

  /// 注: 构造函数入参的默认值必须是常量。
  const MarqueeView(
      {Key? key,
        this.pauseDuration = const Duration(milliseconds: 100),
        this.forwardDuration = const Duration(milliseconds: 3000),
        this.scrollSpeed = 40.0,
        required this.child})
      : super(key: key);

  @override
  _MarqueeViewState createState() => _MarqueeViewState();
}

class _MarqueeViewState extends State<MarqueeView>
    with SingleTickerProviderStateMixin {
  bool _validFlag = true;
  double _boxWidth = 0;
  final ScrollController _controller = ScrollController();

  @override
  void dispose() {
    debugPrint('Track_MarqueeView_dispose');
    _validFlag = false;
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    scroll();
  }

  @override
  Widget build(BuildContext context) {
    /// 使用LayoutBuilder获取组件的大小。
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        _boxWidth = constraints.maxWidth;
        return SingleChildScrollView(
          // 禁止手动滑动。
          physics: const NeverScrollableScrollPhysics(),
          controller: _controller,
          scrollDirection: Axis.horizontal,
          child: Container(
            //两侧的边距
            padding: EdgeInsets.symmetric(horizontal: _boxWidth),
            child: widget.child,
          ),
        );
      },
    );
  }

  void scroll() async {
    while (_validFlag) {
      debugPrint('Track_MarqueeView_scroll');
      await Future.delayed(widget.pauseDuration);
      if (_boxWidth <= 0) {
        continue;
      }
      _controller.jumpTo(_boxWidth);
      // 两个方向: Curves.easeIn 和 Curves.easeOut 。
      await _controller.animateTo(_controller.position.maxScrollExtent,
          duration: Duration(
              seconds:
              (_controller.position.maxScrollExtent / widget.scrollSpeed)
                  .floor()),
          curve: Curves.easeOut);
    }
  }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

flutter 文字从左到右轮播滚动,跑马灯 的相关文章

  • 使用 AVFoundation 裁剪 AVAsset 视频

    我在用AVCaptureMovieFileOutput录制一些视频 我使用显示预览层AVLayerVideoGravityResizeAspectFill稍微放大 我遇到的问题是最终的视频较大 包含预览期间不适合屏幕的额外图像 这是预览和生
  • Android-工具栏中的SearchView

    我只想在我的应用程序中添加 searchview 但我不想搜索任何东西 只是我想要用户输入的查询 到目前为止 我尝试了这段代码 但是当我运行我的应用程序时它崩溃了 Update 我尝试了这个 但即使我的应用程序崩溃了 main menu x
  • 查找已用应用程序名称的捆绑包/开发人员

    我正在尝试将应用程序上传到应用程序商店并收到以下错误 很容易理解 The App Name you have entered has already been used 该应用程序不在 iTunes 上 有什么方法可以找出谁拥有该应用程序或
  • 没有调用addToBackStack,片段仍然添加到backstack,为什么?

    我正在制作我的片段更换器助手类 但我遇到了一些问题 我称之为FragmentChanger 它有一个fragmentContainer 这是一个ViewGroup 其中包含我想展示的所有片段 我已经做了我自己的replace Fragmen
  • Android ListView setSelection() 似乎不起作用

    我有一个ListActivity实现onListItemClick 并调用doSomething 类的功能 后者包含l setSelection position where l is the ListView object 现在有一个on
  • 如何从android获取应用程序安装时间

    我尝试了一些方法 但没有成功 请帮助我 PackageManager pm context getPackageManager ApplicationInfo appInfo pm getApplicationInfo app packag
  • Integer.parseInt("0x1F60A") 以 NumberformatException 结束

    我尝试从数据库中获取长字符串内的表情符号代码 格式如下 0x1F60A 所以我可以访问代码 但它将是String 起初 我尝试通过执行以下操作来转换变量tv setText beforeEmo getEmijoByUnicode int e
  • Android GCM 服务器的 API 密钥

    我有点困惑我应该为 GCM 服务器使用哪个 API 密钥 在文档中它说使用 android api 密钥 这对我不起作用并且总是给出未经授权的 http developer android com google gcm gs html ht
  • Android模拟器分配内存失败8

    当我尝试从 Eclipse 运行 WXGA800 模拟器时 出现如下错误 Failed to allocate memory 8 This application has requested the Runtime to terminate
  • 如何从 Facebook 邀请好友到 Android 应用程序? - 给出错误

    我正在开发一个 Android 应用程序 我正在努力将 邀请朋友 功能添加到我的应用程序中 它转到我的AppLinkUrl成功但显示错误 我的清单代码如下
  • 删除Android所有语言中的字符串

    我有一个包含多个翻译的应用程序 我想删除一些字符串 我怎样才能重构并删除它们一次 例如在默认情况下strings xml文件并自动将删除传播到其他翻译的其他 strings xml 文件 您可以通过 Android Studio 中的 翻译
  • 使用嵌套的 hashmap 参数发送 volley 请求

    我正在使用 android volley 框架向我的服务器发送 jsonobject 请求 get 请求工作正常 现在我想发送一个带有请求参数的 post 请求 该请求参数是嵌套的 hashmap 我重写 getparams 方法 但它期望
  • Android:打开和关闭SQLite数据库

    我正在开发Android应用程序 我经常在其中访问本地数据库 该数据库可以从不同的主题访问 因此我遇到了数据库的协调问题 我使用以下open and close method public void open mDb mDbHelper g
  • 在视图之间传递核心数据实体变量

    我无法理解如何在视图之间使用核心数据实体变量 为了更好地理解我的问题是什么 我的代码如下 View A 基本上 您必须将完整预算实体或相关预算实体的 ID 从视图 A 传递到视图 B 由于不知道您的应用程序的视图层次结构和逻辑 我假设您选择
  • 检测 ListView(或 ScrollView)内的滚动位置

    我正在构建一个聊天室应用程序 其中每 X 秒就会轮询一次新事件 每次发生这种情况时 此代码都会使用新数据更新 RoomAdapter ArrayAdapter 的自定义子类 并将其滚动到底部 RoomAdapter adapter Room
  • XCode 4.5 给我“SenTestingKit/SenTestKit.h”文件未找到,但适用于 4.4.1

    我刚刚安装了 XCode 4 5 它在我现有的项目之一上给了我一个 SenTestingKit SenTestingKit h 文件未找到错误 此错误仅发生在 XCode 4 5 中 但它在 4 4 1 上编译正常 我已经检查过SenTes
  • Flutter 网络图像作为 Google 地图标记

    我想在屏幕上的谷歌地图上添加网络图像作为标记 API确实支持一个功能Bitmapdescriptor fromBytes 但是 我不知道如何将它与网络图像一起使用 BitmapDescriptor fromBytes byteData 首先
  • ios - 在哪里放置 s.static_framework = true

    我在 CocoaPods 中的级别为 0 当我使用pod install有一个错误说 The Pods App target has transitive dependencies that include static framework
  • ios 导航 堆栈操作

    我在尝试从 iOS 应用程序操作导航堆栈时遇到问题 或者至少是由于这种操纵而产生的行为 我的情况 我有 3 个 ViewController 控制器a显示多个级别 控制器 b 是游戏视图 控制器 c 是某种分数 显然 我将在控制器 a 中选
  • ios - Gamekit 的 GKOctree 未找到元素

    我正在尝试使用GKOctree https developer apple com documentation gameplaykit gkoctree用于高效检索 3D 空间中的对象 然而 以下代码似乎没有按预期工作 import Gam

随机推荐

  • 极坐标转化

    在数学中 极坐标系是一个二维坐标系统 该坐标系统中任意位置可由一个夹角和一段相对原点 极点的距离来表示 极坐标系的应用领域十分广泛 包括数学 物理 工程 航海 航空以及机器人领域 两点间的关系用夹角和距离很容易表示时 极坐标系便显得尤为有用
  • Spring课件

    容器与 bean 1 容器接口 BeanFactory 接口 典型功能有 getBean ApplicationContext 接口 是 BeanFactory 的子接口 它扩展了 BeanFactory 接口的功能 如 国际化 通配符方式
  • Python自动化

    usr bin env python os system gnome terminal e bash c ls exec bash coding utf 8 import linecache import pyautogui import
  • Nginx(代理)+Tomcat(Java)+Apache(PHP)共用80端口

    解决的核心问题是 使用一个80端口 根据域名或者子域名 同时访问java php运行环境 1 下载nginx 官网下载链接 http nginx org en download html 接下来我以nginx Windows 1 16 0
  • 『学Vue2+Vue3』智慧商城项目

    智慧商城 接口文档 https apifox com apidoc shared 12ab6b18 adc2 444c ad11 0e60f5693f66 doc 2221080 演示地址 http cba itlike com publi
  • 在ubuntu下安装vscode

    ubuntu22 04下通过命令安装vscode 1 为什么不用应用市场直接下载 最近下载ubuntu22 04版本 不知道为啥里面的应用软件下载不了vscode 尝试在网上解决 gt 卸载自带的应用市场 安装另外的一种 结果失败了 导致原
  • 【路由指令】

    一 linux route add net 192 0 0 0 netmask 255 0 0 0 gw 192 180 30 1 sudo route add net 192 180 0 0 netmask 255 255 0 0 gw
  • python爬取今日头条后台数据_爬虫爬取今日头条数据代码实现

    课程链接 讲师的公众号文章 今日头条数据抓取及持久化 完整代码版 含IP和用户代理 mp weixin qq com 课程代码 抓取并持久化user agent工具utils py 对于爬虫工具 需要设置发起请求的user agent im
  • Spring Boot 框架基础

    Spring Boot 框架基础 基础案例 pom xml
  • BUCK LX_OUT Snubber电路

    1 问题 开关节点振铃 过冲 开关节点过冲会导致LX OUT管脚的电压过高 如果超过datasheet上的maximum值 就有可能影响DCDC芯片寿命 2 产生振铃 过冲的原因 2 1 输入电容摆放不正确 2 2 输出电感 电容摆放不正确
  • STM32F103滴答计时器之delay函数

    如果使用FreeRTOS void delay us u32 nus u32 ticks u32 told tnow tcnt 0 u32 reload SysTick gt LOAD ticks nus fac us tcnt 0 del
  • k8s删除deployment_k8s灾备指南(Velero)

    最近验证了使用velero对k8s进行灾难恢复 操作验证步骤如下 1 下载verlero 解压 tar xvf
  • java案例15:模拟订单号生成

    思路 模拟订单号生成 超市购物时 小票上都会有一个订单号 且订单号唯一 编写程序模拟订单系统中订单号的生成 生成订单号时 使用年月日和毫秒值组合生成唯一订单号 例如 给一个包括年月日和毫秒值的数组arr 2023 0401 1100 将其拼
  • git解决代码冲突、合并代码

    共同开发时提交代码会遇到代码冲突 第一次遇到就手足无措的我 打算写一篇博客记录下来 下次遇到稳如老狗 一 远程代码已有更新记录 忘记拉取远程代码 直接提交 单人开发时 我没有先拉远程代码再提交的习惯 千万不要学习 一定要先拉代码再提交 导致
  • 关于odoo条码显示问题处理

    这里分几种情况 1 第一种情况 打印的单据不显示条码 这种情况比较常见 一般是 没有对应字体导致 不能正常显示条码 单据打印的条码 一片空白 无条码的情况 这种情况是因为 条码的字体没有安装 需要安装一下 这里我会把资源上传 大家可以下载
  • Mac texlive+texstudio 如何手动安装宏包

    1 从CTAN上搜索自己需要的package 2 以subfigure为例 选择第一个结果 下载下来 3 解压下载后的文件 这时候发现里面并没有 sty文件 在终端中输入latex subfigure即可生成需要的sty文件 将整个文件夹保
  • nuxt.js-------koa2项目,环境错误一次性解决

    nuxt js虽然好用但是自己的脚手架安装完全是坑 cnpm run dev 报错确实main js node环境nuxt版本不匹配 在网上找了很多解决方法没有解决 就一次性把所有脚手架和环境都升级到最新版本 npm install bac
  • Nginx 负载均衡 - fair

    学习在 Nginx 中使用 fair 模块 第三方 来实现负载均衡 fair 采用的不是内建负载均衡使用的轮换的均衡算法 而是可以根据页面大小 响应时间智能的进行负载均衡 1 准备工作 nginx upstream fair 官方下载地址
  • 使用Nuxt.js框架开发(SSR)服务端渲染项目

    SSR 服务端渲染的优缺点 优点 1 前端耗时少 首屏加载速度快 因为后端拼接完了html 浏览器只需要直接渲染出来 2 有利于SEO 因为在后端有完整的html页面 所以爬虫更容易爬取获得信息 更有利于seo 3 无需占用客户端资源 即解
  • flutter 文字从左到右轮播滚动,跑马灯

    参考 description begin 跑马灯 根据滚动方向可以分为 横向滚动 和 纵向滚动 此页实现的跑马灯是 横向滚动的 description end import dart async import package flutter