1、地址:github-DanmakuFlameMaster
2、依赖:
implementation 'com.github.ctiao:DanmakuFlameMaster:0.9.25'
implementation 'com.github.ctiao:ndkbitmap-armv7a:0.9.21'
// Other ABIs: optional
implementation 'com.github.ctiao:ndkbitmap-armv5:0.9.21'
implementation 'com.github.ctiao:ndkbitmap-x86:0.9.21'
3、初始化:
xml文件:
<master.flame.danmaku.ui.widget.DanmakuView
android:id="@+id/hot_barrage_chat_dkv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
//弹幕View
DanmakuView danmakuView = findViewById(R.id.hot_barrage_chat_dkv);
弹幕配置:
// 滚动弹幕最大显示4行
HashMap<Integer, Integer> maxLinesPair = new HashMap<Integer, Integer>();
maxLinesPair.put(BaseDanmaku.TYPE_SCROLL_RL, 4);
//设置是否禁止重叠
HashMap<Integer, Boolean> overlappingEnablePair = new HashMap<Integer, Boolean>();
overlappingEnablePair.put(BaseDanmaku.TYPE_SCROLL_LR, true);
overlappingEnablePair.put(BaseDanmaku.TYPE_FIX_BOTTOM, true);
//初始化配置
DanmakuContext danmakuContext = DanmakuContext.create();
danmakuContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN, 3) //设置描边样式
.setDuplicateMergingEnabled(false)//是否启用合并重复弹幕
.setScrollSpeedFactor(1.2f) //设置弹幕滚动速度系数,只对滚动弹幕有效
.setScaleTextSize(1.2f)
.setCacheStuffer(new SpannedCacheStuffer(), null) // 图文混排使用SpannedCacheStuffer 设置缓存绘制填充器,默认使用{@link SimpleTextCacheStuffer}只支持纯文字显示, 如果需要图文混排请设置{@link SpannedCacheStuffer}如果需要定制其他样式请扩展{@link SimpleTextCacheStuffer}|{@link SpannedCacheStuffer}
.setMaximumLines(maxLinesPair) //设置最大显示行数
.preventOverlapping(overlappingEnablePair); //设置防弹幕重叠,null为允许重叠
//设置解析器
baseDanmakuParser = new BaseDanmakuParser() {
@Override
protected IDanmakus parse() {
return new Danmakus();
}
};
//配置弹幕
danmakuView.setCallback(this);
danmakuView.prepare(baseDanmakuParser, danmakuContext);
danmakuView.showFPS(false); //是否显示FPS
danmakuView.enableDanmakuDrawingCache(true);
//监听回调
@Override
public void updateTimer(DanmakuTimer timer) {
//定时器更新的时候回调
}
@Override
public void drawingFinished() {
//弹幕绘制完成时回调
}
@Override
public void danmakuShown(BaseDanmaku danmaku) {
//弹幕展示的时候回调
}
@Override
public void prepared() {
//弹幕准备好的时候回调,这里启动弹幕
if (danmakuView != null)
danmakuView.start();
}
注意一定要在prepared 开启弹幕
4、发送文字弹幕
文字弹幕
public void addDanmaku(boolean isLive, String sendContent) {
if (danmakuView == null || danmakuContext == null) {
return;
}
//创建一个弹幕对象,这里后面的属性是设置滚动方向的!
BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
if (danmaku == null || sendContent == null) {
return;
}
//弹幕显示的文字
danmaku.text = sendContent;
//设置相应的边距,这个设置的是四周的边距
danmaku.padding = 5;
// 可能会被各种过滤器过滤并隐藏显示,若果是本机发送的弹幕,建议设置成1;
danmaku.priority = 0;
//是否是直播弹幕
danmaku.isLive = isLive;
danmaku.setTime(danmakuView.getCurrentTime() + 3600);
//设置文字大小
danmaku.textSize = danmaTextSize;
//设置文字颜色
danmaku.textColor = textColor;
//设置阴影的颜色
danmaku.textShadowColor = Color.WHITE;
//设置线颜色
danmaku.underlineColor = Color.GREEN;
//设置背景颜色
danmaku.borderColor = Color.GREEN;
//添加这条弹幕,也就相当于发送
danmakuView.addDanmaku(danmaku);
}
5、发送图片文字弹幕
public void addDanmaKuShowTextAndImage(boolean isLive) {
if (danmakuView == null || danmakuContext == null) {
return;
}
BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
if (danmaku == null) {
return;
}
Drawable drawable = getContext().getResources().getDrawable(R.mipmap.ic_launcher);
drawable.setBounds(0, 0, 100, 100);
SpannableStringBuilder spannable = createSpannable(drawable);
danmaku.text = spannable;
danmaku.padding = 5;
danmaku.priority = 0; // 一定会显示, 一般用于本机发送的弹幕
danmaku.isLive = isLive;
danmaku.setTime(danmakuView.getCurrentTime() + 1200);
danmaku.textSize = danmaTextSize;
danmaku.textColor = Color.RED;
danmaku.borderColor = Color.GRAY; // 重要:如果有图文混排,最好不要设置描边(设textShadowColor=0),否则会进行两次复杂的绘制导致运行效率降低
// danmaku.underlineColor = Color.GREEN;
danmakuView.addDanmaku(danmaku);
}
/**
* 创建图文混排模式
*
* @param drawable
* @return
*/
private SpannableStringBuilder createSpannable(Drawable drawable) {
String text = "bitmap";
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);
CenteredImageSpan span = new CenteredImageSpan(drawable);//ImageSpan.ALIGN_BOTTOM);
spannableStringBuilder.setSpan(span, 0, text.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
spannableStringBuilder.append("bitmap图文混bitmap图文混bitmap图文混bitmap图文混");
spannableStringBuilder.setSpan(new BackgroundColorSpan(Color.parseColor("#8A2233B1")), 0, spannableStringBuilder.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
return spannableStringBuilder;
}
其实弹幕图文、表情、字体变色都是通过 Spannable 来实现。
6.其他 --CacheStufferAdapter
private BaseCacheStuffer.Proxy mCacheStufferAdapter = new BaseCacheStuffer.Proxy() {
private Drawable mDrawable;
/**
* 在弹幕显示前使用新的text,使用新的text
* @param danmaku
* @param fromWorkerThread 是否在工作(非UI)线程,在true的情况下可以做一些耗时操作(例如更新Span的drawblae或者其他IO操作)
* @return 如果不需重置,直接返回danmaku.text
*/
@Override
public void prepareDrawing(final BaseDanmaku danmaku, boolean fromWorkerThread) {
if (danmaku.text instanceof Spanned) { // 根据你的条件检查是否需要需要更新弹幕
// FIXME 这里只是简单启个线程来加载远程url图片,请使用你自己的异步线程池,最好加上你的缓存池
new Thread() {
@Override
public void run() {
String url = "https://img1.baidu.com/it/u=2648389307,756086504&fm=26&fmt=auto";
InputStream inputStream = null;
Drawable drawable = mDrawable;
if (drawable == null) {
try {
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
inputStream = urlConnection.getInputStream();
drawable = BitmapDrawable.createFromStream(inputStream, "bitmap");
mDrawable = drawable;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
}
}
if (drawable != null) {
drawable.setBounds(0, 0, 100, 100);
SpannableStringBuilder spannable = createSpannable(drawable);
danmaku.text = spannable;
if (danmakuView != null) {
danmakuView.invalidateDanmaku(danmaku, false);
}
return;
}
}
}.start();
}
}
@Override
public void releaseResource(BaseDanmaku danmaku) {
// TODO 重要:清理含有ImageSpan的text中的一些占用内存的资源 例如drawable
if (danmaku != null) {
CharSequence text = danmaku.text;
if (text instanceof SpannableStringBuilder) {
danmaku.text = "";
}
}
}
};
以上就是DanmakuFlameMaster使用。