很棒的Android弹幕效果实例

很多项目需要用到弹幕效果,尤其是在播放视频的时候需要一起显示别人发的弹幕,也包括自己的发的。

今天就试着写了一下这个效果。

思路就是将从右往左的动画效果,字体内容,字体大小,弹幕平移速度等属性一起与TextView封装成BarrageItem,并将控制效果与BarrageItem绑定在BarrageView进行显示。思路还是比较简单的。这里没有考虑到带有表情的弹幕,我会持续更新的。

先看效果:

项目目录结构:

接下来定义Barrageitem.class : 这个类就将TextView与从右往左的动画效果,字体内容,字体大小,弹幕平移速度等属性绑定。

public class BarrageItem { 

  public TextView textView; 

  public int textColor; 

  public String text; 

  public int textSize; 

  // 移动速度
  public int moveSpeed; 

  // 垂直方向显示的位置
  public int verticalPos; 

  // 字体显示占据的宽度
  public int textMeasuredWidth; 

}

然后定义BarrageView,由于弹幕的字体颜色大小和移动速度都是随机的,需要定义最大最小值来限定它们的范围,然后通过产生随机数来设置它们在这个范围内的值。另外还需要定义弹幕的文本内容,这里是直接写死的一些固定值。

BarrageView.class:

public class BarrageView extends RelativeLayout { 

  private Context mContext; 

  private BarrageHandler mHandler = new BarrageHandler(); 

  private Random random = new Random(System.currentTimeMillis()); 

  // 两个弹幕的最小间隔时间
  private static final long BARRAGE_GAP_MIN_DURATION = 1000; 

  // 两个弹幕的最大间隔时间
  private static final long BARRAGE_GAP_MAX_DURATION = 2000; 

  // 速度,ms
  private int maxSpeed = 12000; 

  // 速度,ms
  private int minSpeed = 8000; 

  // 文字最大值
  private int maxSize = 50; 

  // 文字最小值
  private int minSize = 10; 

  private int totalHeight = 0; 

  private int lineHeight = 0;// 每一行弹幕的高度 

  private int totalLine = 0;// 弹幕的行数 

  private String[] itemText = { "他们都说蔡睿智很帅,但他总觉得自己很丑",
      "他们都说蔡睿智是男神,但他只觉得自己是男生", "蔡睿智不是男神,蔡睿智是男生", "蔡睿智貌似是gay", "蔡睿智是弯的",
      "蔡睿智是弯的,还好现在掰回来了", "他承受了他这个年纪不该有的机智与帅气,他好累",
      "我恨自己的颜值,我觉得自己的才华才是吸引别人的地方", "他为什么对妹子不感兴趣呢?为什么?", "他为什么不想谈恋爱","他不会去爱别人,同时也不希望别人去爱他,他已经习惯一个人了",
      "他的心里是否住着一个苍老的小孩", "他的世界一直就是他和他的影子,直到遇到她", "她引导他走出了自己的世界,改变他的很多看法",
      "他渐渐的发现自己已经离不开他,他选择不再去压抑自己", "因为他已经不是那个无能为力的年纪","她经常说他 高冷,现在越来越觉得他恨闷骚","开始他一直与她保持朋友距离,但他发现自己根本作不到"};
  private int textCount; 

  public BarrageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mContext = context;
    _init();
  } 

  public BarrageView(Context context, AttributeSet attrs) {
    this(context, null, 0); 

  } 

  public BarrageView(Context context) {
    this(context, null); 

  } 

  private void _init() {
    textCount = itemText.length;
    int duration = (int) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math
        .random());
    mHandler.sendEmptyMessageDelayed(0, duration);
  } 

  @Override
  public void onWindowFocusChanged(boolean hasWindowFocus) {
    super.onWindowFocusChanged(hasWindowFocus);
    totalHeight = getMeasuredHeight();
    lineHeight = getLineHeight();
    totalLine = totalHeight / lineHeight;
  } 

  private void generateItem() {
    BarrageItem item = new BarrageItem();
    String tx = itemText[(int) (Math.random() * textCount)];
    int sz = (int) (minSize + (maxSize - minSize) * Math.random());
    item.textView = new TextView(mContext);
    item.textView.setText(tx);
    item.textView.setTextSize(sz);
    item.textView.setTextColor(Color.rgb(random.nextInt(256),
        random.nextInt(256), random.nextInt(256)));
    item.textMeasuredWidth = (int) getTextWidth(item, tx, sz);
    item.moveSpeed = (int) (minSpeed + (maxSpeed - minSpeed)
        * Math.random());
    if (totalLine == 0) {
      totalHeight = getMeasuredHeight();
      lineHeight = getLineHeight();
      totalLine = totalHeight / lineHeight;
    }
    item.verticalPos = random.nextInt(totalLine) * lineHeight;
    showBarrageItem(item);
  } 

  private void showBarrageItem(final BarrageItem item) {
    int leftMargin = this.getRight() - this.getLeft()
        - this.getPaddingLeft();
    LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
        LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    params.topMargin = item.verticalPos;
    this.addView(item.textView, params);
    Animation anim = generateTranslateAnim(item, leftMargin);
    anim.setAnimationListener(new Animation.AnimationListener() { 

      @Override
      public void onAnimationStart(Animation arg0) { 

      } 

      @Override
      public void onAnimationRepeat(Animation arg0) { 

      } 

      @Override
      public void onAnimationEnd(Animation arg0) {
        item.textView.clearAnimation();
        BarrageView.this.removeView(item.textView);
      }
    });
    item.textView.startAnimation(anim);
  } 

  private TranslateAnimation generateTranslateAnim(BarrageItem item,
      int leftMargin) {
    TranslateAnimation anim = new TranslateAnimation(leftMargin,
        -item.textMeasuredWidth, 0, 0);
    anim.setDuration(item.moveSpeed);
    anim.setInterpolator(new AccelerateDecelerateInterpolator());
    anim.setFillAfter(true);
    return anim;
  } 

  /**
   * 计算TextView中字符串的长度
   *
   * @param item
   * @param text
   *      要计算的字符串
   * @param Size
   *      字体大小
   * @return TextView中字符串的长度
   */
  public float getTextWidth(BarrageItem item, String text, float Size) {
    Rect bounds = new Rect();
    TextPaint paint;
    paint = item.textView.getPaint();
    paint.getTextBounds(text, 0, text.length(), bounds);
    return bounds.width();
  } 

  /**
   * 获得每一行弹幕的最大高度
   */
  private int getLineHeight() {
    BarrageItem item = new BarrageItem();
    String tx = itemText[0];
    item.textView = new TextView(mContext);
    item.textView.setText(tx);
    item.textView.setTextSize(maxSize); 

    Rect bounds = new Rect();
    TextPaint paint;
    paint = item.textView.getPaint();
    paint.getTextBounds(tx, 0, tx.length(), bounds);
    return bounds.height();
  } 

  class BarrageHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      generateItem();
      // 每个弹幕产生的时间随机
      int duration = (int) ((BARRAGE_GAP_MAX_DURATION - BARRAGE_GAP_MIN_DURATION) * Math
          .random());
      this.sendEmptyMessageDelayed(0, duration);
    }
  } 

}

如果弹幕显示的垂直位置是随机的,就会出现垂直方向上弹幕重叠的情况,所以需要根据高度对垂直方向按照弹幕高度的最大值等分,然后让弹幕在这些指定的垂直位置随机分布。这个值在onWindowFocusChanged里计算,因为在这个方法中通过View的getMeasuredHeight()得到的高度不为空。

MainActivity.class:

<span style="font-size:18px;">public class MainActivity extends Activity { 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
}</span>

以上就是弹幕的源码,其实我觉得这里少了自己发送弹幕的功能,我会在以后的更新上去的,共勉。

(0)

相关推荐

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

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

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

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

  • Android 实现仿网络直播弹幕功能详解及实例

    Android 网络直播弹幕                最近看好多网络电视,播放器及直播都有弹幕功能,自己周末捣鼓下并实现,以下是网上的资料,大家可以看下. 现在网络直播越来越火,网络主播也逐渐成为一种新兴职业,对于网络直播,弹幕功能是必须要有的,如下图: 首先来分析一下,这个弹幕功能是怎么实现的,首先在最下面肯定是一个游戏界面View,然后游戏界面上有弹幕View,弹幕的View必须要做成完全透明的,这样即使覆盖在游戏界面的上方也不会影响到游戏的正常观看,只有当有人发弹幕消息时,再将消息绘

  • Android自制精彩弹幕效果

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

  • Android实现炫酷的网络直播弹幕功能

    现在网络直播越来越火,网络主播也逐渐成为一种新兴职业,对于网络直播,弹幕功能是必须要有的,如下图: 首先来分析一下,这个弹幕功能是怎么实现的,首先在最下面肯定是一个游戏界面View,然后游戏界面上有弹幕View,弹幕的View必须要做成完全透明的,这样即使覆盖在游戏界面的上方也不会影响到游戏的正常观看,只有当有人发弹幕消息时,再将消息绘制到弹幕的View上面就可以了,下方肯定还有有操作界面View,可以让用户来发弹幕和送礼物的功能,原理示意图如下所示: 参照原理图,下面一步一步来实现这个功能.

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

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

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

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

  • Android弹幕框架 黑暗火焰使基本使用方法

    今天我将分享由BiliBili开源的Android弹幕框架(DanmakuFlameMaster)的学习经验. 我是将整个框架以model的形式引入项目中的,这样更方便的观察源码.也可以通过依赖的方式注入进来 dependencies { compile 'com.github.ctiao:DanmakuFlameMaster:0.5.3' } 先放一下我要做成的效果图: 页面分析 从上图来看,整个UI分成了三层.最下面是视频层,中间是弹幕层,顶层是控制层.现在市场上主流的视频直播软件大多都是这

  • 实例解析如何在Android应用中实现弹幕动画效果

    在B站或者其他视频网站看视频时,常常会打开弹幕效果,边看节目边看大家的吐槽.弹幕看起来很有意思,今天我们就来实现一个简单的弹幕效果. 从直观上,弹幕效果就是在一个ViewGroup上增加一些View,然后让这些View移动起来.所以,整体的实现思路大概是这样的: 1.定义一个RelativeLayout,在里面动态添加TextView. 2.这些TextView的字体大小.颜色.移动速度.初始位置都是随机的. 3.将TextView添加到RelativeLayout的右边缘,每隔一段时间添加一个

  • 很棒的Android弹幕效果实例

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

  • 移动端H5开发 Turn.js实现很棒的翻书效果

    最近CTO给我分配了一个移动端H5开发的任务,主要功能是需要实现翻书效果,我听过主要需求后,当时是呀!!!接下来自己尝试使用 fullPage.js和Swiper来实现翻书效果,结果效果都不是非常的理想,后来想起自己曾经做过PC版的翻书效果,当时使用的是Turn.js,查过其相关API后,整个人突然豁然开朗呀,使用Turn.js 完全可以解决当前我接手这个项目的所有需求呀.现在将个人的学习总结如下,若有不正确的地方,欢迎读者给与批评指正! Turn.js的官方网址: http://www.tur

  • jQuery实现的弹幕效果完整实例

    本文实例讲述了jQuery实现的弹幕效果.分享给大家供大家参考,具体如下: 看视频的时候老是会出现一些弹幕,对于这个看着很高大上的特效,其实也不难实现. 先来看看运行效果: 下面将整个代码显示出来: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>www.jb51.net弹幕</title> <st

  • Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果(实例代码)

    自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果.的确HorizontalScrollView可以实现Gallery的效果,但是HorizontalScrollView存在一个很大的问题,如果你仅是用来展示少量的图片,应该是没问题的,但是如果我希望HorizontalScrollView可以想ViewPager一样,既可以绑定数据集(动态改变图片),还能做到,不管多少图片都不会OOM(ViewPager内

  • Android实现桌面悬浮窗、蒙板效果实例代码

    现在很多安全类的软件,比如360手机助手,百度手机助手等等,都有一个悬浮窗,可以飘浮在桌面上,方便用户使用一些常用的操作. 今天这篇文章,就是介绍如何实现桌面悬浮窗效果的. 首先,看一下效果图. 悬浮窗一共分为两个部分,一个是平常显示的小窗口,另外一个是点击小窗口显示出来的二级悬浮窗口. 首先,先看一下这个项目的目录结构. 最关键的就是红框内的四个类. 首先,FloatWindowService是一个后台的服务类,主要负责在后台不断的刷新桌面上的小悬浮窗口,否则会导致更换界面之后,悬浮窗口也会随

  • Android自定义view实现太极效果实例代码

    Android自定义view实现太极效果实例代码 之前一直想要个加载的loading.却不知道用什么好,然后就想到了太极图标,最后效果是有了,不过感觉用来做loading简直丑到爆!!! 实现效果很简单,我们不要用什么贝塞尔曲线啥的,因为太极无非就是圆圆圆,只要画圆就ok了.来上代码: 因为有黑有白,所以定义2个画笔分别为黑和白. private void inital() { whitePaint = new Paint(); whitePaint.setAntiAlias(true); wh

  • Android 自定义view实现进度条加载效果实例代码

    这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

  • Android简单实现弹幕效果

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

随机推荐