目前主流的android直播平台好多,龙珠,B站,虎牙,斗鱼,熊猫TV.......,大多数玩过直播的人都知道可以发送弹幕和主播互动,那么弹幕效果是怎么实现的呢,这里简单的做了一个demo,先看效果图:
具体实现思路:
界面中分为三部分:底层是播放界面VideoView,然后有一个全透明的遮罩层,用来显示弹幕,上层遮罩就是输入编辑框.这里我们使用bilibili开源的库来实现弹幕效果.
首先引用Jar:
compile'com.github.ctiao:DanmakuFlameMaster:0.7.3'
然后实现xml布局:
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
tools:context="com.wanjianhua.mockpanda.MainActivity">
android:id="@+id/diveo_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
android:id="@+id/danmaku_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
android:id="@+id/operation_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="#fff"
android:visibility="gone"
>
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
android:id="@+id/send"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="send"
/>
这里先将编辑框隐藏
Activity中添加使用:
DanmakuView 弹幕视图
DanmakuContext.create(); 创建视图
BaseDanmaku 设置弹幕边距颜色等
具体代码如下:
public classMainActivityextendsAppCompatActivity {
privateVideoViewdiveo_view;
private booleanshowDanmaku;
privateDanmakuViewdanmakuView;
privateDanmakuContextdanmakuContext;
privateLinearLayoutoperation_layout;
privateEditTextedit_text;
privateButtonsend;
privateBaseDanmakuParserparser=newBaseDanmakuParser() {
@Override
protectedIDanmakusparse() {
return newDanmakus();
}
};
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
// private void checkPremission() {
// if (Build.VERSION.SDK_INT >= 23) {
// //android 6.0动态申请权限
// if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//
// }
// }
// }
private voidinitView() {
operation_layout= (LinearLayout) findViewById(R.id.operation_layout);
edit_text= (EditText) findViewById(R.id.edit_text);
send= (Button) findViewById(R.id.send);
diveo_view= (VideoView) findViewById(R.id.diveo_view);
// diveo_view.setVideoPath(Environment.getExternalStorageDirectory() + "/lol.mp4");
// diveo_view.setVideoPath("rtsp://v2.cache2.c.youtube.com/CjgLENy73wIaLwm3JbT_%ED%AF%80%E" +
// "D%B0%819HqWohMYESARFEIJbXYtZ29vZ2xlSARSB3Jlc3VsdHNg_vSmsbeSyd5JDA==/0/0/0/video.3gp");
diveo_view.setVideoURI(Uri.parse("android.resource://"+ getPackageName()
+"/"+ R.raw.hdmi));
diveo_view.start();
danmakuView= (DanmakuView) findViewById(R.id.danmaku_view);
danmakuView.enableDanmakuDrawingCache(true);
danmakuView.setCallback(newDrawHandler.Callback() {
@Override
public voidprepared() {
showDanmaku=true;
danmakuView.start();
generateSomeDanmaku();
}
@Override
public voidupdateTimer(DanmakuTimer timer) {
}
@Override
public voiddanmakuShown(BaseDanmaku danmaku) {
}
@Override
public voiddrawingFinished() {
}
});
danmakuContext= DanmakuContext.create();
danmakuView.prepare(parser,danmakuContext);
danmakuView.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
if(operation_layout.getVisibility() == View.GONE) {
operation_layout.setVisibility(View.VISIBLE);
}else if(operation_layout.getVisibility() == View.VISIBLE) {
operation_layout.setVisibility(View.GONE);
}
}
});
send.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
//发送消息
addDanmaku(edit_text.getText().toString(), true);
}
});
}
private voidaddDanmaku(String content, booleanwithborder) {
BaseDanmaku danmaku =danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
danmaku.text= content;
danmaku.padding=5;
danmaku.textSize= sp2px(20);
danmaku.textColor= Color.WHITE;
danmaku.setTime(danmakuView.getCurrentTime());
if(withborder) {
danmaku.borderColor= Color.GREEN;
}
danmakuView.addDanmaku(danmaku);
}
/**
*随即生成一些内容测试
*/
private voidgenerateSomeDanmaku() {
newThread(newRunnable() {
@Override
public voidrun() {
while(showDanmaku) {
inttime =newRandom().nextInt(300);
String content =""+ time + time;
addDanmaku(content, false);
try{
Thread.sleep(time);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public intsp2px(floatvalue) {
final floatfontScale = getResources().getDisplayMetrics().scaledDensity;
return(int) (value * fontScale +0.5f);
}
@Override
protected voidonPause() {
super.onPause();
if(danmakuView!=null&&danmakuView.isPrepared()) {
danmakuView.pause();
}
}
@Override
protected voidonResume() {
super.onResume();
if(danmakuView!=null&&danmakuView.isPrepared() &&danmakuView.isPaused()) {
danmakuView.resume();
}
}
@Override
protected voidonDestroy() {
super.onDestroy();
showDanmaku=false;
if(danmakuView!=null) {
danmakuView.release();
danmakuView=null;
}
}
@Override
public voidonWindowFocusChanged(booleanhasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus && Build.VERSION.SDK_INT>=19) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_FULLSCREEN| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_FULLSCREEN| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
}
github源码下载地址,欢迎star,和交流