栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android exoplayer subtitleview 字幕 居中`置顶`置底位置设置方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android exoplayer subtitleview 字幕 居中`置顶`置底位置设置方法

解决办法

        Talk is cheap. Show me the code.

// 在subtitleView.setCues的地方使用newCues就可以啦~
override fun onCues(cues: MutableList) {
            super.onCues(cues)

           val newCues = ArrayList()
            for (cue in cues) {
                val newCue = cue.buildUpon().apply {
                    setLine(0.5f, Cue.LINE_TYPE_FRACTION)
                    lineAnchor = Cue.ANCHOR_TYPE_MIDDLE
                }.build()

                newCues.add(newCue)
            }
            
            subtitleView.setCues(newCues)
        }

copy上面的代码, 字幕就可以居中啦, 置顶就把0.5改成0, 置底就改成1 over~

下面分析一下上面代码的形成过程, 有兴趣的可以看一哈~

起因        

        我们的首席设计师小姐姐说字幕要居中才好看, 虽然不知道咋设置, 但咱不能在漂亮妹子面前丢人鸭!(行, 给爷等着~)
        在成功的google和百度失败之后, 我决定自己分析源码解决. 当然也是为了让我们成为更有效率的 google/百度 程序员, 于是我就把分析经历整理分享出来~

源码分析

        下面给个源码分析, 基于exoplayer版本 2.14.1

首先看SubtitleView是个什么东西, 如下

public final class SubtitleView extends frameLayout implements TextOutput {
    ...
}

ok, SubtitleView只是一个ViewGroup, 不做具体的字幕显示, 那谁来显示字幕呢, 当然是他的childView啦, 而childView当然是通过addView引入的, 搜索addView看到, 如下

public SubtitleView(Context context, @Nullable AttributeSet attrs) {
    ...

    CanvasSubtitleOutput canvasSubtitleOutput = new CanvasSubtitleOutput(context, attrs);
    output = canvasSubtitleOutput;
    innerSubtitleView = canvasSubtitleOutput;
    addView(innerSubtitleView);
    ...
  }

可以看到, 在SubtitleView初始化的时候, 添加了一个childView -> CavasSubtitleOutput, 那绘制字幕一定就在这里面啦! 但是CavasSubtitleOutput中没有重写onDraw函数, 而是重写了dispatchDraw, 这个不是本文的重点(其实是我不了解~), 大家可以自行搜索~

然后就是一层一层地调用跟进啦, 最终我们在SubtitlePainter -> setupTextLayout 函数中, 找到如下代码

if (cueLine != Cue.DIMEN_UNSET) {
      if (cueLineType == Cue.LINE_TYPE_FRACTION) {
        int anchorPosition = Math.round(parentHeight * cueLine) + parentTop;
        textTop =
            cueLineAnchor == Cue.ANCHOR_TYPE_END
                ? anchorPosition - textHeight
                : cueLineAnchor == Cue.ANCHOR_TYPE_MIDDLE
                    ? (anchorPosition * 2 - textHeight) / 2
                    : anchorPosition;
      } else {
        // cueLineType == Cue.LINE_TYPE_NUMBER
        int firstLineHeight = textLayout.getLineBottom(0) - textLayout.getLineTop(0);
        if (cueLine >= 0) {
          textTop = Math.round(cueLine * firstLineHeight) + parentTop;
        } else {
          textTop = Math.round((cueLine + 1) * firstLineHeight) + parentBottom - textHeight;
        }
      }
...
}

重点就是textTop了, 他的值就是y轴上字幕的实际摆放位置啦,  代码中有稍显复杂的三目表达式, 认真看一下就能理解了(其实我还是觉得用if更清晰些), 所以我们就可以对cueLine和cuelineAnchor赋值进行字幕的位置更改了.

那么赋值是在哪里呢, 又经过了一段时间的认真查看, 我们知道了Cue的构造函数时私有的, 只能通过builder来创建对象, 所以最终就有了上面的解决办法啦~

      另外就是 cueLineType == Cue.LINE_TYPE_NUMBER 的类型, 这个看起来是根据第一行字幕的高度来定位位置的, 大家可以根据需求来自己定制~

总结

        总体来说分析起来还是挺简单的, 只要了解view的一些原理就容易很多了. 

        楼主是第一次分析源码, 如果文章中有错误的地方, 请各位大佬指点. 以防误导前来学习的同学~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/666266.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号