文章目录 弹幕使用 一、准备工作 二、任务分析与实施 1.MainActitvity 中获取界面控件 2.播放视频 3.初始化弹幕 4.随机生成与添
文章目录
- 弹幕使用
- 一、准备工作
- 二、任务分析与实施
- 1.MainActitvity 中获取界面控件
- 2.播放视频
- 3.初始化弹幕
- 4.随机生成与添加弹幕
- 5.效果展示
弹幕使用
一、准备工作
- 导入播放的视频
- 导入基本组件:VideoView、DanmakuView、EditText、Button
返回顶部
二、任务分析与实施
当点击弹幕界面的时候,界面底部会弹出一个输入框和一个发送按钮,当输入文字并点击按钮后,弹幕会出现一个蓝色框,框中显示刚刚发送的文字;当再次点击弹幕时,界面底部的输入框和按钮消失。
1.MainActitvity 中获取界面控件
public class MainActivity extends AppCompatActivity {// 获取控件
private EditText input;
private Button submit;
private DanmakuView danmaku;
private VideoView videoView;
private DanmakuContext danmakuContext;
private LinearLayout layout;
private boolean showDanmaku;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化界面控件
layout = findViewById(R.id.layout);
input = findViewById(R.id.input);
submit = findViewById(R.id.submit);
danmaku = findViewById(R.id.danmaku);
videoView = findViewById(R.id.videoView);
}
}
返回顶部
2.播放视频
- 在MAinActivity中创建playVido方法用于播放视频文件
private void playVideo() {
// 获取视频路径
String uri = "android.resource://" + getPackageName() + "/" + R.raw.speed;
//String uri = "G:\\Projects\\AndroidStudioProjects\\Barrage\\app\\src\\main\\res\\raw\\sun.mp4";
if (uri != null) {
// 配置到 VideoView 组件中
videoView.setVideoURI(Uri.parse(uri));
videoView.start();
} else {
// 将背景设置为透明
videoView.getBackground().setAlpha(0);
}
}
返回顶部
3.初始化弹幕
- 在MAinActivity中创建一个initDanmaku方法,用于初始化弹幕并调用弹幕的随机生成与添加方法
private BaseDanmakuParser parser = new BaseDanmakuParser() {
@Override
protected IDanmakus parse() {
return new Danmakus();
}
};
// 初始化弹幕
private void initDanmaku(){
danmaku.setCallback(new DrawHandler.Callback() {
@Override
public void prepared() {
showDanmaku = true;
danmaku.start(); // 开始弹幕
generateDanmakus(); // 随机生成弹幕的方法
}
@Override
public void updateTimer(DanmakuTimer timer) {
}
@Override
public void danmakuShown(BaseDanmaku danmaku) {
}
@Override
public void drawingFinished() {
}
});
// 创建 DanmakuContext 上下文对象
danmakuContext = DanmakuContext.create();
// 开始缓存
danmaku.enableDanmakuDrawingCache(true);
// 弹幕view准备 --- 传入解析器
danmaku.prepare(parser,danmakuContext);
// 弹幕组件点击事件
danmaku.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (layout.getVisibility() == View.GONE){
layout.setVisibility(View.VISIBLE);
} else {
layout.setVisibility(View.GONE);
}
}
});
// 提交按钮点击事件
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = input.getText().toString();
if (!TextUtils.isEmpty(content)){
addDanmaku(content,true); // 添加一条弹幕
input.setText("");
}
}
});
}
返回顶部
4.随机生成与添加弹幕
generateDanmakus():随机生成弹幕
addDanmaku():添加弹幕至弹幕组件
// 添加弹幕private void addDanmaku(String content, boolean border) {
// 创建弹幕对象,设置从右向左滚动
BaseDanmaku baseDanmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
baseDanmaku.text = content; // 设置内容
baseDanmaku.padding = 6; // 设置边距
baseDanmaku.textSize = 25; // 设置弹幕字体大小
baseDanmaku.textColor = Color.WHITE; // 设置弹幕字体颜色
baseDanmaku.setTime(danmaku.getCurrentTime()); // 设置当前时间
if (border){
baseDanmaku.borderColor = Color.BLUE; // 设置边框颜色
}
// 添加弹幕至弹幕视图组件中
danmaku.addDanmaku(baseDanmaku);
}
// 随机生成弹幕
private void generateDanmakus() {
// 启用线程随机生成弹幕
new Thread(new Runnable() {
@Override
public void run() {
while (showDanmaku) {
int num = new Random().nextInt(300);
String content = ""+num;
addDanmaku(content,false);
try {
Thread.sleep(num);
} catch (Exception e){
e.printStackTrace();
}
}
}
}).start();
}
返回顶部
5.效果展示
完整代码:
package com.example.barrage;import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.VideoView;
import java.util.Random;
import master.flame.danmaku.controller.DrawHandler;
import master.flame.danmaku.danmaku.model.BaseDanmaku;
import master.flame.danmaku.danmaku.model.DanmakuTimer;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
import master.flame.danmaku.ui.widget.DanmakuView;
public class MainActivity extends AppCompatActivity {
// 获取控件
private EditText input;
private Button submit;
private DanmakuView danmaku;
private VideoView videoView;
private DanmakuContext danmakuContext;
private LinearLayout layout;
private boolean showDanmaku;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化界面控件
layout = findViewById(R.id.layout);
input = findViewById(R.id.input);
submit = findViewById(R.id.submit);
danmaku = findViewById(R.id.danmaku);
videoView = findViewById(R.id.videoView);
// 调用方法
playVideo();
initDanmaku();
}
// 播放视频
private void playVideo() {
// 获取视频路径
String uri = "android.resource://" + getPackageName() + "/" + R.raw.speed;
//String uri = "G:\\Projects\\AndroidStudioProjects\\Barrage\\app\\src\\main\\res\\raw\\sun.mp4";
if (uri != null) {
// 配置到 VideoView 组件中
videoView.setVideoURI(Uri.parse(uri));
videoView.start();
} else {
// 将背景设置为透明
videoView.getBackground().setAlpha(0);
}
}
// 弹幕解析器
private BaseDanmakuParser parser = new BaseDanmakuParser() {
@Override
protected IDanmakus parse() {
return new Danmakus();
}
};
// 初始化弹幕
private void initDanmaku(){
danmaku.setCallback(new DrawHandler.Callback() {
@Override
public void prepared() {
showDanmaku = true;
danmaku.start(); // 开始弹幕
generateDanmakus(); // 随机生成弹幕的方法
}
@Override
public void updateTimer(DanmakuTimer timer) {
}
@Override
public void danmakuShown(BaseDanmaku danmaku) {
}
@Override
public void drawingFinished() {
}
});
// 创建 DanmakuContext 上下文对象
danmakuContext = DanmakuContext.create();
// 开始缓存
danmaku.enableDanmakuDrawingCache(true);
// 弹幕view准备 --- 传入解析器
danmaku.prepare(parser,danmakuContext);
// 弹幕组件点击事件
danmaku.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (layout.getVisibility() == View.GONE){
layout.setVisibility(View.VISIBLE);
} else {
layout.setVisibility(View.GONE);
}
}
});
// 提交按钮点击事件
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = input.getText().toString();
if (!TextUtils.isEmpty(content)){
addDanmaku(content,true); // 添加一条弹幕
input.setText("");
}
}
});
}
// 添加弹幕
private void addDanmaku(String content, boolean border) {
// 创建弹幕对象,设置从右向左滚动
BaseDanmaku baseDanmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
baseDanmaku.text = content; // 设置内容
baseDanmaku.padding = 6; // 设置边距
baseDanmaku.textSize = 25; // 设置弹幕字体大小
baseDanmaku.textColor = Color.WHITE; // 设置弹幕字体颜色
baseDanmaku.setTime(danmaku.getCurrentTime()); // 设置当前时间
if (border){
baseDanmaku.borderColor = Color.BLUE; // 设置边框颜色
}
// 添加弹幕至弹幕视图组件中
danmaku.addDanmaku(baseDanmaku);
}
// 随机生成弹幕
private void generateDanmakus() {
// 启用线程随机生成弹幕
new Thread(new Runnable() {
@Override
public void run() {
while (showDanmaku) {
int num = new Random().nextInt(300);
String content = ""+num;
addDanmaku(content,false);
try {
Thread.sleep(num);
} catch (Exception e){
e.printStackTrace();
}
}
}
}).start();
}
@Override
protected void onPause() {
super.onPause();
if (danmaku!=null && danmaku.isPrepared()){
danmaku.pause();
}
}
@Override
protected void onResume() {
super.onResume();
if (danmaku!=null && danmaku.isPrepared() && danmaku.isPaused()){
danmaku.resume();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
showDanmaku = false;
if (danmaku!=null){
danmaku.release();
danmaku= null;
}
}
}<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="262dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteY="30dp" />
<master.flame.danmaku.ui.widget.DanmakuView
android:id="@+id/danmaku"
android:layout_width="match_parent"
android:layout_height="122dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp" />
<!-- 按钮和文本编辑框放在同一布局中,实现显示隐藏功能 -->
<LinearLayout
android:id="@+id/layout"
android:layout_width="372dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginStart="20dp"
android:layout_marginTop="295dp"
android:visibility="gone">
<EditText
android:id="@+id/input"
android:layout_width="233dp"
android:layout_height="match_parent"
android:layout_marginEnd="20dp"
android:hint="请输入弹幕" />
<Button
android:id="@+id/submit"
android:layout_width="104dp"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:text="发送"
android:textSize="20dp">
</Button>
</LinearLayout>
</RelativeLayout>
返回顶部