转载请注明出处 作者:AboutJoke ( http://blog.csdn.net/u013200308 ) 原文链接:http://blog.csdn.net/u013200308/article/details/57123100
现在各大视屏网站都有了弹幕功能,但显示效果最好的非b站莫属了。如果你也想拥有和b站一样炫酷的弹幕效果,那么就跟着我来一步步实现。
首先放上地址
https://github.com/Bilibili/DanmakuFlameMaster
使用也很简单
repositories { jcenter()}dependencies { compile 'com.github.ctiao:DanmakuFlameMaster:0.6.4' compile 'com.github.ctiao:ndkbitmap-armv7a:0.6.4' # Other ABIs: optional compile 'com.github.ctiao:ndkbitmap-armv5:0.6.4' compile 'com.github.ctiao:ndkbitmap-x86:0.6.4'}到这里我们就将库导入了as了,接下来就是真正的使用。
<master.flame.danmaku.ui.widget.DanmakuView android:id="@+id/danmaku_view" android:layout_width="match_parent" android:layout_height="match_parent" />用来承载弹幕显示的布局,有了布局就可以去实现代码了,一些方法我也都标上了注释。
//初始化弹幕层 public void initDanmaku() { mDanmakuContext = DanmakuContext.create(); HashMap<Integer, Integer> maxLine = new HashMap<>(); maxLine.put(BaseDanmaku.TYPE_SCROLL_RL, 3);// 滚动弹幕最大显示3行 // 设置是否禁止重叠 HashMap<Integer, Boolean> overlappingEnablePair = new HashMap<Integer, Boolean>(); overlappingEnablePair.put(BaseDanmaku.TYPE_SCROLL_RL, true); overlappingEnablePair.put(BaseDanmaku.TYPE_FIX_TOP, true); mDanmakuContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN, 3)//设置描边样式 .setDuplicateMergingEnabled(false)//是否启用合并重复弹幕 .setScrollSpeedFactor(1.2f) //设置弹幕滚动速度系数,只对滚动弹幕有效 .setScaleTextSize(1.2f)//设置字体缩放 .setMaximumLines(maxLine)//设置最大显示行数 .PReventOverlapping(overlappingEnablePair);//设置防弹幕重叠 if (mDanmakuView != null) { 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() { } }); //弹幕解析器,如不想使用使用xml格式的可以以自己定义或默认// mParser = new BaseDanmakuParser() {// @Override// protected IDanmakus parse() {// return new Danmakus();// }// }; mParser = createParser(this.getResources().openRawResource(R.raw.comments)); mDanmakuView.showFPS(true);//显示fps mDanmakuView.enableDanmakuDrawingCache(true);//显示弹幕绘制缓冲 mDanmakuView.prepare(mParser, mDanmakuContext); } }b站的弹幕使用的是xml格式保存的,而a站的弹幕使用的是json格式,如果你也准备使用xml格式可以借鉴b站的解析方式,而或者这两种格式你都不使用的话,可以使用默认的弹幕解析器。
mParser = new BaseDanmakuParser() { @Override protected IDanmakus parse() { return new Danmakus(); } };接下来需要创建弹幕解析器,用来解析不同格式的弹幕,如前面所说,你的弹幕格式是xml或json就需要这一步。
//创建解析器对象,解析输入流 private BaseDanmakuParser createParser(InputStream stream) { if (stream == null) { return new BaseDanmakuParser() { @Override protected Danmakus parse() { return new Danmakus(); } }; } //DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI) xml解析 //DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_ACFUN) json文件格式解析 ILoader loader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI); try { loader.load(stream); } catch (IllegalDataException e) { e.printStackTrace(); } BaseDanmakuParser parser = new BiliDanmukuParser(); IDataSource<?> dataSource = loader.getDataSource(); parser.load(dataSource); return parser; }弹幕解析器的主要作用是接受从服务器传来的弹幕文件,解析后将其一一展示出来,那么我们发出去的弹幕则需要一个单独的方法来实现弹幕的发送,在这一步你可以对发送的弹幕进行个性化定制。
//添加弹幕 public void addDanmaku(boolean islive, String msg, boolean isUs) { BaseDanmaku danmaku = mDanmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL); if (danmaku == null || mDanmakuView == null) { return; } danmaku.text = msg;//弹幕内容 danmaku.padding = 5; danmaku.priority = 1;//0 表示可能会被各种过滤器过滤并隐藏显示 1 表示一定会显示, 一般用于本机发送的弹幕 danmaku.isLive = islive; //是否是直播弹幕 danmaku.setTime(mDanmakuView.getCurrentTime() + 1200); //显示时间 danmaku.textSize = 18f * (mParser.getDisplayer().getDensity() - 0.6f); //字体大小 danmaku.textColor = Color.WHITE; danmaku.textShadowColor = Color.parseColor("#333333");// 阴影颜色,可防止白色字体在白色背景下不可见 if (isUs) danmaku.borderColor = Color.YELLOW; //对于自己发送的弹幕可以加框显示,0表示无边框 mDanmakuView.addDanmaku(danmaku); }有了发送弹幕的方法,那我们当然也得有接收弹幕的布局,在这里我是用PopupWindow来实现,你可以去使用你习惯的方式。来看看我们要实现的布局
从图片里可以看到右边有数字的标示,那是因为我还要实现一个弹幕字数的限制,一次如果发送太多字数的弹幕难免太影响观看了。对于字数的限制也很简单,可以使用EditText的TextWatcher来实现,如果有不会的可以去源码里面查看。那么到此我们就实现了弹幕的播放和发送,赶快来看看效果,不过在看效果之前我们还得再写几句代码,mDanmakuView.release();别忘记去onDestroy()和onBackPressed()里面去释放资源。好了,来看看效果吧。
录屏效果看起来有点差,真机效果可是棒棒哒。另外附上源码地址:
https://github.com/AboutJoke/DanmuDemo
新闻热点
疑难解答