5.4.6弹幕
为了方便大家拓展功能,我们加入了一些简单的功能比如点赞、弹幕等。这里给大家介绍一个同样是由Bilibili站开源的DanmakuFlameMaster弹幕解析绘制框架。它也是目前为止Android上最好的弹幕框架,目前已经被优酷、土豆、斗鱼、ACFUN等APP软件使用。
它的特性
- 使用多种方式(View/SurfaceView/TextureView)实现高效绘制
- B站xml弹幕格式解析
- 基础弹幕精确还原绘制
- 支持mode7特殊弹幕
- 多核机型优化,高效的预缓存机制
- 支持多种显示效果选项实时切换
- 实时弹幕显示支持
- 换行弹幕支持/运动弹幕支持
- 支持自定义字体
- 支持多种弹幕参数设置
- 支持多种方式的弹幕屏蔽
集成方法
在Gradle中引入的方式
repositories {
jcenter()
}
dependencies {
compile 'com.github.ctiao:DanmakuFlameMaster:0.9.21'
compile 'com.github.ctiao:ndkbitmap-armv7a:0.9.21'
# Other ABIs: optional
compile 'com.github.ctiao:ndkbitmap-armv5:0.9.21'
compile 'com.github.ctiao:ndkbitmap-x86:0.9.21'
}
在文件中加入弹幕控件
<master.flame.danmaku.ui.widget.DanmakuView
android:id="@+id/danmakuViewID"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Activity中的功能代码也简单,注册弹幕控件并添加数据即可
public class PullActivity extends AppCompatActivity{
private DanmakuView mDanmakuView;//弹幕组件
private DanmakuContext danmakuContext;//弹幕内容
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pull_view);
mDanmakuView = findViewById(R.id.danmakuViewID);
//初始化弹幕组件
initDanmaku();
}
//初始化弹幕组件
private void initDanmaku() {
//给弹幕视图设置回调,在准备阶段获取弹幕信息并开始
mDanmakuView.setCallback(new DrawHandler.Callback() {
@Override
public void prepared() {
mDanmakuView.start();
}
@Override
public void updateTimer(DanmakuTimer timer) {
}
@Override
public void danmakuShown(BaseDanmaku danmaku) {
}
@Override
public void drawingFinished() {
}
});
//缓存,提升绘制效率
mDanmakuView.enableDanmakuDrawingCache(true);
//DanmakuContext主要用于弹幕样式的设置
danmakuContext = DanmakuContext.create();
danmakuContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN,3);//描边
danmakuContext.setDuplicateMergingEnabled(false);//重复合并
danmakuContext.setScrollSpeedFactor(1.2f);//弹幕滚动速度
//让弹幕进入准备状态,传入弹幕解析器和样式设置
mDanmakuView.prepare(parser,danmakuContext);
//显示fps、时间等调试信息
mDanmakuView.showFPS(false);
}
// 随机生成一些弹幕内容以供测试
private void generateSomeDanmaku() {
for (int i = 0 ; i < 100 ; i ++){
int time = new Random().nextInt(300);
String content = "" + time + time;
addDanmaku(content, false);
}
}
/**
* 向弹幕View中添加一条弹幕
* @param content 弹幕的具体内容
* @param withBorder 弹幕是否有边框
*/
private void addDanmaku(String content, boolean withBorder) {
//弹幕实例BaseDanmaku,传入参数是弹幕方向
BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
danmaku.text = content;
danmaku.padding = 5;
danmaku.textSize = sp2px(20);
danmaku.textColor = Color.WHITE;
int time = new Random().nextInt(900);
danmaku.setTime(mDanmakuView.getCurrentTime() + time*10);
//加边框
if (withBorder) {
danmaku.borderColor = Color.GREEN;
}
mDanmakuView.addDanmaku(danmaku);
}
@Override
protected void onPause() {
super.onPause();
if (mDanmakuView != null && mDanmakuView.isPrepared()) {
mDanmakuView.pause();
}
}
@Override
protected void onResume() {
super.onResume();
if (mDanmakuView != null && mDanmakuView.isPrepared() && mDanmakuView.isPaused()) {
mDanmakuView.resume();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//退出时释放资源
if (mDanmakuView != null) {
mDanmakuView.release();
mDanmakuView = null;
}
}