今天简单介绍一下开源的弹幕引擎---danmakuView

  使用之前在build.gradle里面添加下面这一条(目前我使用的工具是AndroidStudio 3.1.2)

  implementation 'com.github.ctiao:DanmakuFlameMaster:0.3.8'

  库导入完成之后一定不要忘记 Sync now (emmmm,相信你应该不会忘)

1.设计布局

  首先设计布局,布局文件就很好理解了,采用了谷歌最新的ConstraintLayout布局,简单实用,内部放置一个VideoView用来播放视频,EditText用来输入弹幕,Button用来发送弹幕,介绍Over

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:app="http://schemas.android.com/apk/res-auto"
  5. xmlns:tools="http://schemas.android.com/tools"
  6. android:id="@+id/activity_main"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"
  9. android:background="#000"
  10. tools:context=".MainActivity">
  11. <VideoView
  12. android:id="@+id/videoview"
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content" />
  15. <master.flame.danmaku.ui.widget.DanmakuView
  16. android:id="@+id/danmaku"
  17. android:layout_width="match_parent"
  18. android:layout_height="match_parent"
  19. android:layout_marginBottom="8dp"
  20. android:layout_marginLeft="8dp"
  21. android:layout_marginStart="8dp"
  22. android:layout_marginTop="8dp"
  23. app:layout_constraintBottom_toBottomOf="parent"
  24. app:layout_constraintEnd_toEndOf="parent"
  25. app:layout_constraintStart_toStartOf="parent"
  26. app:layout_constraintTop_toTopOf="parent" />
  27. <LinearLayout
  28. android:id="@+id/ly_send"
  29. android:layout_width="match_parent"
  30. android:layout_height="50dp"
  31. android:background="#FFF"
  32. android:orientation="horizontal"
  33. android:visibility="gone"
  34. app:layout_constraintBottom_toBottomOf="parent">
  35. <EditText
  36. android:id="@+id/et_text"
  37. android:layout_width="0dp"
  38. android:layout_height="match_parent"
  39. android:layout_weight="1" />
  40. <Button
  41. android:id="@+id/btn_send"
  42. android:layout_width="wrap_content"
  43. android:layout_height="match_parent"
  44. android:text="发送" />
  45. </LinearLayout>
  46. </android.support.constraint.ConstraintLayout>

2.界面逻辑

  点击屏幕,底部会显示一个输入框和一个发送按钮,当输入文字并点击发送之后,屏幕上会出现一个蓝色框,里面是刚刚输入的文字,再次点击屏幕,底部的输入框和发送按钮消失。Over

  1. package com.project.software.company;
  2. import android.graphics.Color;
  3. import android.net.Uri;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.os.Bundle;
  6. import android.text.TextUtils;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.EditText;
  10. import android.widget.LinearLayout;
  11. import android.widget.VideoView;
  12. import org.w3c.dom.Text;
  13. import java.util.Random;
  14. import master.flame.danmaku.controller.DrawHandler;
  15. import master.flame.danmaku.danmaku.model.BaseDanmaku;
  16. import master.flame.danmaku.danmaku.model.DanmakuTimer;
  17. import master.flame.danmaku.danmaku.model.IDanmakus;
  18. import master.flame.danmaku.danmaku.model.android.DanmakuContext;
  19. import master.flame.danmaku.danmaku.model.android.Danmakus;
  20. import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
  21. import master.flame.danmaku.ui.widget.DanmakuView;
  22. public class MainActivity extends AppCompatActivity {
  23. private boolean showDanmaku;
  24. private DanmakuView danmakuView;
  25. private DanmakuContext danmakuContext;
  26. private Button sendButton;
  27. private LinearLayout sendLayout;
  28. private EditText editText;
  29. private VideoView videoView;
  30. @Override
  31. protected void onCreate(Bundle savedInstanceState) {
  32. super.onCreate(savedInstanceState);
  33. setContentView(R.layout.activity_main);
  34. initView();
  35. playVideo();
  36. initDanmaku();
  37. }
  38. //初始化界面控件
  39. private void initView() {
  40. videoView = findViewById(R.id.videoview);
  41. sendLayout = findViewById(R.id.ly_send);
  42. sendButton = findViewById(R.id.btn_send);
  43. editText = findViewById(R.id.et_text);
  44. danmakuView = findViewById(R.id.danmaku);
  45. }
  46. //播放视频
  47. private void playVideo() {
  48. String uri = "android.resource://"+getPackageName()+"/"+R.raw.sun;
  49. if(uri !=null){
  50. videoView.setVideoURI(Uri.parse(uri));
  51. videoView.start();
  52. } else {
  53. videoView.getBackground().setAlpha(0); //将背景设为透明
  54. }
  55. }
  56. //创建弹幕解析器
  57. private BaseDanmakuParser parser = new BaseDanmakuParser() {
  58. @Override
  59. protected IDanmakus parse() {
  60. return new Danmakus();
  61. }
  62. };
  63. //初始化弹幕
  64. private void initDanmaku(){
  65. danmakuView.setCallback(new DrawHandler.Callback() { //设置回调函数
  66. @Override
  67. public void prepared() {
  68. showDanmaku = true;
  69. danmakuView.start(); //开始弹幕
  70. generateDanmakus(); //开始随机生成弹幕方法
  71. }
  72. @Override
  73. public void updateTimer(DanmakuTimer timer) {
  74. }
  75. @Override
  76. public void drawingFinished() {
  77. }
  78. });
  79. danmakuContext = danmakuContext.create();
  80. danmakuView.enableDanmakuDrawingCache(true); //提升屏幕绘制效率
  81. danmakuView.prepare(parser,danmakuContext); //进行弹幕准备
  82. //为danmakuView设置点击事件
  83. danmakuView.setOnClickListener(new View.OnClickListener() {
  84. @Override
  85. public void onClick(View v) {
  86. if(sendLayout.getVisibility() == View.GONE){
  87. sendLayout.setVisibility(View.VISIBLE); //显示布局
  88. } else {
  89. sendLayout.setVisibility(View.GONE); //隐藏布局
  90. }
  91. }
  92. });
  93. //为“发送”按钮设置点击事件
  94. sendButton.setOnClickListener(new View.OnClickListener() {
  95. @Override
  96. public void onClick(View v) {
  97. String content = editText.getText().toString();
  98. if(!TextUtils.isEmpty(content)){
  99. addDanmaku(content,true); //添加一条弹幕
  100. editText.setText("");
  101. }
  102. }
  103. });
  104. }
  105. //添加一条弹幕
  106. //content 弹幕的具体内容
  107. //border 弹幕是否有边框
  108. private void addDanmaku(String content,boolean border){
  109. //创建弹幕对象,TYPE_SCROLL_RL表示从左向右滚动的弹幕
  110. BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
  111. danmaku.text = content;
  112. danmaku.padding = 6;
  113. danmaku.textSize = 30;
  114. danmaku.textColor = Color.WHITE; //弹幕文字颜色
  115. danmaku.time = danmakuView.getCurrentTime();
  116. if(border){
  117. danmaku.borderColor = Color.BLUE; //弹幕文字边框的颜色
  118. }
  119. danmakuView.addDanmaku(danmaku); //添加一条弹幕
  120. }
  121. /*
  122. 随机生成一些弹幕的内容
  123. */
  124. private void generateDanmakus(){
  125. new Thread(new Runnable() {
  126. @Override
  127. public void run() {
  128. while(showDanmaku){
  129. int num = new Random().nextInt(300);
  130. String content = ""+num;
  131. addDanmaku(content,false);
  132. try{
  133. Thread.sleep(num);
  134. }catch (InterruptedException e){
  135. e.printStackTrace();
  136. }
  137. }
  138. }
  139. }).start();
  140. }
  141. protected void onPause() {
  142. super.onPause();
  143. if(danmakuView != null && danmakuView.isPrepared()){
  144. danmakuView.pause();
  145. }
  146. }
  147. protected void onResume() {
  148. super.onResume();
  149. if(danmakuView !=null && danmakuView.isPrepared() && danmakuView.isPaused()){
  150. danmakuView.resume();
  151. }
  152. }
  153. protected void onDestroy() {
  154. super.onDestroy();
  155. showDanmaku = false;
  156. if(danmakuView != null){
  157. danmakuView.release();
  158. danmakuView = null;
  159. }
  160. }
  161. }

  下面简单解释一下代码,在onCreate()方法中调用了三个初始化函数:

    1.initView()用来初始化界面控件

    2.playVideo()用来播放视频(将视频名称为run的视频放入raw文件夹下面)

    3.initDanmaku()用来初始化屏幕

  接下来是添加弹幕,在发送按钮的点击事件中调用了addDanmaku(content,true)函数,将输入的内容传递过来,并在该函数中设置弹幕的一些属性

  当然,光有自己输入的弹幕是不美观的,还要添加一些别人输入的弹幕,这样显得更真实一些,generateDanmakus()函数就做到了这一点,不过这里选择的是随机生成一些数字

  剩下的onPause(),onResume(),onDestroy()方法就比较简单,我就不一一介绍了

  最后,如果你觉得竖屏和标题栏不好看,可以在MainActivity的《activity》标签(这里我不得不用中文符号,英文符号会出错)中加入下面这一句,使之横屏:

    android:screenOrientation="landscape"

  在《application》标签(这里也是同样的问题)中下入下面这一句,去掉标题栏:

    android:theme="@style/Theme.AppCompat.Light.NoActionBar"

  最最最后,贴图看效果

  此文Over

浅谈DanmakuView的更多相关文章

  1. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  2. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  3. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  4. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  5. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  6. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  7. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  8. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

  9. 浅谈Angular的 $q, defer, promise

    浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00  博客园-原创精华区 原文  http://www.cnblogs.com/big-snow/ ...

随机推荐

  1. opencv 视觉项目学习笔记(二): 基于 svm 和 knn 车牌识别

    车牌识别的属于常见的 模式识别 ,其基本流程为下面三个步骤: 1) 分割: 检测并检测图像中感兴趣区域: 2)特征提取: 对字符图像集中的每个部分进行提取: 3)分类: 判断图像快是不是车牌或者 每个 ...

  2. Git 实用技巧:git stash

    我们经常会遇到这样的情况: 正在dev分支开发新功能,做到一半时有人过来反馈一个bug,让马上解决,但是新功能做到了一半你又不想提交,这时就可以使用git stash命令先把当前进度保存起来.然后切换 ...

  3. 在Docker for Windows中运行GUI程序

    Docker运行GUI原理 Docker目前大多应用在服务器领域,那么在Docker中可以运行GUI程序吗?怀着好奇心google了一番,还真有人写了一篇文章 running-gui-applicat ...

  4. python之“装饰器”

    在python里装饰器 其定义:装饰器就是一个函数,用来装饰其他函数,就是给其他函数添加功能. 装饰器有两个特点: 1.装饰器不修改被装饰函数的源码: 2.装饰器不锈钢被装饰函数的调用方式. 在编程中 ...

  5. shiro@RequiresPermission的设置

    public class MyShiroRealm extends AuthorizingRealm { //slf4j记录日志,可以不使用 private Logger logger = Logge ...

  6. [程序人生]那些IT界“活久见”的奇葩现象

    常言道,人活久了什么稀奇古怪的事都会见到.本文盘点几件刚毕业工作时想当然,工作若干年后啪啪打脸的“奇葩”事. (1)去年推荐一朋友来我们公司面试时,朋友说起当年她去某游戏公司时,那公司HR说这家公司是 ...

  7. C# - 协变、逆变 看完这篇就懂了

    1. 基本概念 官方:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型.[MSDN] 公式: ...

  8. JSP学习笔记(3)——JSTL 标签库

    JSP Standard Tag Lib,名为JSP标准标签库,设计的目的主要用来方便我们将数据输出,而不是使用JSP中的语法<% %> <%= %> <%! %> ...

  9. 【sybase】You can’t run SELECT INTO in this database的解决办法

    进入master 数据库,使用sp_dboption test ,'select into',true命令(其中test为要设置可用的数据库)

  10. Java-手动搭建SSM(Maven)

    一.环境部署 操作系统:windows10专业版 jdk:1.8.0_144 IDE:eclipse-oxygen 服务器:tomcat 9.0 数据库:mysql 5.7.18 Maven:3.54 ...