Android Flutter实现弹幕效果

目录
  • 前言
  • 通用弹幕实现方案
  • ListView弹幕方案实现
    • 基本框架
    • 轮播滚动
    • 轮询算法
    • 点击事件

前言

需求要点如下:

  • 弹幕行数为3行,每条弹幕相互依靠但不存在重叠
  • 每条弹幕可交互点击跳转
  • 滚动速度恒定 触摸不可暂停播放
  • 弹幕数据固定一百条且支持轮询播放

弹幕排序规则如下:

1 4 7

2 5 8

3 6 9

通用弹幕实现方案

Flutter Dev Package已有开源弹幕实现组件,这里举例barrage_page的实现方式(大多数实现底层逻辑基本一样)。

基本架构采用Stack然后向布局中提交弹幕布局,添加时设置好弹幕偏移量来设置弹幕位置。

Stack(fit: StackFit.expand, children: <Widget>[
        widget.child,
        _controller.isEnabled
            ? Stack(
            fit: StackFit.loose,
            children: <Widget>[]
              ..addAll(_widgets.values ?? const SizedBox()))
            : const SizedBox(),
      ]);
    });

弹幕效果代码

但因为每条弹幕可能会出现重叠情况无法合理定位每条弹幕的位置因此放弃该方案。

PS:widget只有在build到布局后才能获取到它基础信息(相对位置信息,宽高等)就无法计算出所有弹幕的位置信息。

ListView弹幕方案实现

最先想到使用瀑布流flutter_staggered_grid_view实现弹幕布局但由于组件暂时不支持横向布局就放弃了。

基本框架

采用三个ListView实现每一行弹幕效果。虽然不太推荐以这种形式实现但从快速实现效果来说是比较简单便捷兜底方案。(可以实现但不推荐)

Container(
  height: 200,
  child: Column(
    children: [
      Expanded(
        child: ListView.builder(
          scrollDirection: Axis.horizontal,
          controller: scrollController1,
          itemBuilder: (context, index) {
            return Common.getWidget(index,
                height: 30, width: random.nextInt(100).toDouble());
          },
        ),
      ),
      Expanded(
          child: ListView.builder(
        scrollDirection: Axis.horizontal,
        controller: scrollController2,
        itemBuilder: (context, index) {
          return Common.getWidget(index,
              height: 30, width: random.nextInt(100).toDouble());
        },
      )),
      Expanded(
          child: ListView.builder(
        scrollDirection: Axis.horizontal,
        controller: scrollController3,
        itemBuilder: (context, index) {
          return Common.getWidget(index,
              height: 30, width: random.nextInt(100).toDouble());
        },
      ))
    ],
  ),
)

轮播滚动

添加定时器periodic定时每秒钟执行一次scrollControlleranimateTo方法移动偏移量并且偏移量不断累加。

其次ListView支持无限滑动只要ListView.builder不设置itemCount就能实现。

Timer _timer;

scroll = () {
  offset += 100;
  scrollController1.animateTo(offset,
      duration: Duration(seconds: 1), curve: Curves.linear);
  scrollController2.animateTo(offset,
      duration: Duration(seconds: 1), curve: Curves.linear);
  scrollController3.animateTo(offset,
      duration: Duration(seconds: 1), curve: Curves.linear);
};
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
  scroll();
});

轮询算法

ListView支持无限滑动后itemBuilder回调下标Index会超出数据源最大值。因此数据源也需要支持无限轮询来配合列表滚动。start表示弹幕开始取值,这里设置为(0,1,2);index表示itemBuilder回调下标Index

int findIndex(int start, int index) {
  index = start + index * 3;
  if (expressList.length < index) {
    index = index % (expressList.length - 1); // 取余
  } else if (expressList.length == index) { // 是否是最后一个数据
    index = start;
    if (index >= expressList.length) { // 还需要判断数据源是否比start还小
      index = (index % expressList.length - 1);
    }
  }
  return index;
}

点击事件

一切都实现得很顺利最终就是弹幕点击实现。但实际上当ListViewscrollController在执行animateTo时其实点击操作是失效的,ListView无法响应点击事件。只有当animateTo操作结束之后再执行点击才能执行点击。因此若要实现这个功能只能先将Timer暂停再执行一次点击,再一次点击不可能是用户再去触发,这里只能采用模拟点击形式实现。

PS:ListView无法响应点击事件具体原因还待研究,个人猜测列表做动画时对外部触摸事件进行了屏蔽处理。

GestureDetector(
  onTapUp: (details){
   // 点击抬起之后暂停定时器
    _timer?.cancel();
    // 模拟一次点击
    Timer(Duration(milliseconds: 100),() {
      GestureBinding.instance.handlePointerEvent(PointerAddedEvent(pointer: 0,position: details.globalPosition));
      GestureBinding.instance.handlePointerEvent(PointerDownEvent(pointer: 0,position: details.globalPosition));
      GestureBinding.instance.handlePointerEvent(PointerUpEvent(pointer: 0,position: details.globalPosition));
    });
  },
  child: ListView.builder(
    controller: scrollController,
    physics: NeverScrollableScrollPhysics(),
    itemBuilder: (context, index) {
      return GestureDetector(
        behavior: HitTestBehavior.opaque,
        child: Common.getWidget(index),
        onTap: () {
          // 内部响应点击事件 然后重新设置定时器滚动列表
          _timer = Timer.periodic(Duration(seconds: 1), (timer) {
            scroll();
          });
        },
      );
    },
  ),
);

到此这篇关于Android Flutter实现弹幕效果的文章就介绍到这了,更多相关Flutter弹幕效果内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android自制精彩弹幕效果

    好久没有写过文章,最近发现直播特别的火,很多app都集成了直播的功能,发现有些直播是带有弹幕的,效果还不错,今天心血来潮,特地写了篇制作弹幕的文章. 今天要实现的效果如下: 1.弹幕垂直方向固定 2.弹幕垂直方向随机 上面效果图中白色的背景就是弹幕本身,是一个自定义的FrameLayout,我这里是为了更好的展示弹幕的位置才设置成了白色,当然如果是叠加在VideoView上的话,就需要设置成透明色了. 制作弹幕需要考虑以下几点问题: 1.弹幕的大小可以随意调整 2.弹幕内移动的item(或者称字

  • Android实现自定义的弹幕效果

    一.效果图 先来看看效果图吧~~ 二.实现原理方案 1.自定义ViewGroup-XCDanmuView,继承RelativeLayout来实现,当然也可以继承其他三大布局类哈 2.初始化若干个TextView(弹幕的item View,这里以TextView 为例,当然也可以其他了~),然后通过addView添加到自定义View中 3.通过addView添加到XCDanmuView中,位置在坐标,为了实现 从屏幕外移动进来的效果 我们还需要修改添加进来TextView的位置,以从右向左移动方向

  • Android实现视频弹幕功能

    本文实例为大家分享了Android视频弹幕的具体代码,供大家参考,具体内容如下 效果图: 上图:代码随机生成的弹幕及弹幕输入栏 下图:绿色框的弹幕为用户手动添加发送的弹幕 1.准备工作 准备一个视频文件,将该视频文件放到res/raw目录下. 需要将视频设置为横屏播放,即往配置文件中添加android:screenOrientation="landscape": <activity android:name=".MainActivity" android:co

  • 很棒的Android弹幕效果实例

    很多项目需要用到弹幕效果,尤其是在播放视频的时候需要一起显示别人发的弹幕,也包括自己的发的. 今天就试着写了一下这个效果. 思路就是将从右往左的动画效果,字体内容,字体大小,弹幕平移速度等属性一起与TextView封装成BarrageItem,并将控制效果与BarrageItem绑定在BarrageView进行显示.思路还是比较简单的.这里没有考虑到带有表情的弹幕,我会持续更新的. 先看效果: 项目目录结构: 接下来定义Barrageitem.class : 这个类就将TextView与从右往左

  • Android简单实现弹幕效果

    本文实例为大家分享了Android实现弹幕效果的具体代码,供大家参考,具体内容如下 首先分析一下,他是由三层布局来共同完成的,第一层视频布局,第二层字幕布局,第三层输入框布局,要想让这三个布局在同一页面上,必须用相对布局或帧布局. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/

  • Android自定义View实现弹幕效果

    在很多视频直播中都有弹幕功能,而安卓上没有简单好用的弹幕控件,本文介绍一个自定义弹幕view的demo. 效果图: 思路: 1.自定义Textitem类表示弹幕的信息 2.自定义view继承view,使用ArrayList保存每条Textitem 3.随机生成坐标点绘制每条TextItem,不断变换Text的横坐标实现弹幕的滚动 首先创建弹幕类,弹幕包括坐标,颜色,滚动速度,以及文字内容: public class Textitem { private String content; priva

  • Android Flutter实现弹幕效果

    目录 前言 通用弹幕实现方案 ListView弹幕方案实现 基本框架 轮播滚动 轮询算法 点击事件 前言 需求要点如下: 弹幕行数为3行,每条弹幕相互依靠但不存在重叠 每条弹幕可交互点击跳转 滚动速度恒定 触摸不可暂停播放 弹幕数据固定一百条且支持轮询播放 弹幕排序规则如下: 1 4 7 2 5 8 3 6 9 通用弹幕实现方案 Flutter Dev Package已有开源弹幕实现组件,这里举例barrage_page的实现方式(大多数实现底层逻辑基本一样). 基本架构采用Stack然后向布局

  • Android Flutter实现点赞效果的示例代码

    目录 前言 绘制小手 完整源码 前言 点赞这个动作不得不说在社交.短视频等App中实在是太常见了,当用户手指按下去的那一刻,给用户一个好的反馈效果也是非常重要的,这样用户点起赞来才会有一种强烈的我点了赞的效果,那么今天我们就用Flutter实现一个掘金App上的点赞效果. 首先我们看下掘金App的点赞组成部分,有一个小手,点赞数字.点赞气泡效果,还有一个震动反馈,接下来我们一步一步实现. 知识点:绘制.动画.震动反馈 绘制小手 这里我们使用Flutter的Icon图标中的点赞小手,Icons图标

  • Android Flutter实现有趣的页面滚动效果

    目录 CustomScrollView 简介 改造原代码 让导航栏更有趣 改造后的代码 其他效果 总结 在Flutter 高仿一个某支付价值几个亿的页面这一篇中,我们使用了 ListView 将几个 GridView 组合在一起实现了不同可滑动组件的粘合,但是这里必须要设置禁止 GridView 的滑动,防止多个滑动组件的冲突.这种方式写起来不太方便,事实上 Flutter 提供了 CustomScrollView 来粘合多个滑动组件,并且可以实现更有趣的滑动效果. CustomScrollVi

  • Android Flutter实现GIF动画效果的方法详解

    目录 前言 交错动画机制 代码实现 Interval 介绍 总结 前言 我们之前介绍了不少有关动画的篇章.前面介绍的动画都是只有一个动画效果,那如果我们想对某个组件实现一组动效,比如下面的效果,该怎么办? staggered animation 这个时候我们需要用到组合动效, Flutter 提供了交错动画(Staggered Animation)的方式实现.对于多个 Anmation 对象,可以共用一个 AnimationController,然后在不同的时间段执行动画效果.这就有点像 GIF

  • Android仿斗鱼直播的弹幕效果

    记得之前有位朋友在我的公众号里问过我,像直播的那种弹幕功能该如何实现?如今直播行业确实是非常火爆啊,大大小小的公司都要涉足一下直播的领域,用斗鱼的话来讲,现在就是千播之战.而弹幕则无疑是直播功能当中最为重要的一个功能之一,那么今天,我就带着大家一起来实现一个简单的Android端弹幕效果. 分析 首先我们来看一下斗鱼上的弹幕效果,如下图所示: 这是一个Dota2游戏直播的界面,我们可以看到,在游戏界面的上方有很多的弹幕,看直播的观众们就是在这里进行讨论的. 那么这样的一个界面该如何实现呢?其实并

  • Android EasyBarrage实现轻量级弹幕效果

    本文介绍了Android EasyBarrage实现轻量级弹幕效果,分享给大家,具体如下: 概述 EasyBarrage是Android平台的一种轻量级弹幕效果目前支持以下设置: 自定义字体颜色,支持随机颜色: 自定义字体大小,支持随机字体大小: 支持边框显示,用于区分自己的弹幕和其他弹幕: 自定义边框颜色: 弹幕数据是否允许重复: 自定义单屏显示的最大弹幕数量: 数据不重叠: 支持动态添加弹幕: 不依赖VideoView,数据自动循环显示. github:https://github.com/

  • Android编程实现简易弹幕效果示例【附demo源码下载】

    本文实例讲述了Android编程实现简易弹幕效果.分享给大家供大家参考,具体如下: 首先上效果图,类似于360检测到骚扰电话页面: 布局很简单,上面是一个RelativeLayout,下面一个Button. 功能: (1)弹幕生成后自动从右侧往左侧滚动(TranslateAnimation),弹幕消失后立刻被移除. (2)弹幕位置随机出现,并且不重复(防止文字重叠). (3)字体大小在一定范围内随机改变,字体颜色也可以设置. (4)自定义先减速,后加速的Interpolator,弹幕加速进入.减

随机推荐