安卓漫漫路之实现简单的弹幕.
2017-02-17 21:03
260 查看
直播和看视频中越来越火的控件---弹幕(Danmaku)
本文即介绍怎样实现简单的弹幕效果:咱们使用的是哔哩哔哩开源的弹幕效果库 DanmakuFlameMaster.
必需:首先咱们在项目主工程app/build.gradle中的dependencies闭包中添加如下依赖:
这样我们就将DanmakuFlameMaster库引入到当前项目中了.
开始展示Demo的代码给大家:
首先看咱们的布局文件:
如上,在安卓设备上,一个简单的弹幕Demo就可以实现了.
项目直达下载通道为: Demo_Danmaku
如有问题请多指正,您的指正使我更正确的前行.
本文即介绍怎样实现简单的弹幕效果:咱们使用的是哔哩哔哩开源的弹幕效果库 DanmakuFlameMaster.
必需:首先咱们在项目主工程app/build.gradle中的dependencies闭包中添加如下依赖:
compile 'com.github.ctiao:DanmakuFlameMaster:0.5.3'
这样我们就将DanmakuFlameMaster库引入到当前项目中了.
开始展示Demo的代码给大家:
首先看咱们的布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000"> <VideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true"/> <master.flame.danmaku.ui.widget.DanmakuView android:id="@+id/danmaku_view" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/operation_layout" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:background="#fff" android:visibility="gone"> <EditText android:id="@+id/edit_text" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="发送" /> </LinearLayout> </RelativeLayout> . 背景色为黑色,承载我是用的Video来播放本地或者网络视频,DanmakuView即是咱们的弹幕控件,LinearLayout内包含输入框和发送按钮.当然这些都是最普通的控件,最终的界面当然是由您来设定. 接下来看咱们的MainActivity的代码,如下: . import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.support.v7.app.AppCompatActivity; 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 boolean showDanmaku; //弹幕控件 private DanmakuView danmakuView; //DanmakuContext 字体实例 private DanmakuContext danmakuContext; private BaseDanmakuParser parser = new BaseDanmakuParser() { @Override protected IDanmakus parse() { return new Danmakus(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化VideoView控件 final VideoView videoView = (VideoView) findViewById(R.id.video_view); //指定好VideoView的本地路径地址 SD卡根目录的xxx.mp4文件 videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/xxx.mp4"); //访问网络视频 //Uri uri = Uri.parse("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"); //设置视频控制器 //videoView.setMediaController(new MediaController(this)); //设置视频路径 // videoView.setVideoURI(uri); //开始播放 videoView.start(); new android.os.Handler().postDelayed(new Runnable() { @Override public void run() { videoView.pause(); } }, 0); //初始化弹幕控件 danmakuView = (DanmakuView) findViewById(R.id.danmaku_view); //默认为true 在模拟器上运行有问题 danmakuView.enableDanmakuDrawingCache(true); //看源码得知是一个接口 怎么实现还是要咱们去重写其中的方法 danmakuView.setCallback(new DrawHandler.Callback() { @Override public void prepared() { //把变量置为 true showDanmaku = true; //开始运行弹幕控件 danmakuView.start(); //随机生成一些弹幕内容以供测试 generateSomeDanmaku(); } @Override public void updateTimer(DanmakuTimer timer) { } @Override public void danmakuShown(BaseDanmaku danmaku) { } @Override public void drawingFinished() { } }); //调用 DanmakuContext.create() 完成DanmakuContext的实例化. danmakuContext = DanmakuContext.create(); danmakuView.prepare(parser, danmakuContext); //初始化含有输入框和按钮的线性布局 final LinearLayout operationLayout = (LinearLayout) findViewById(R.id.operation_layout); //初始化发送按钮 final Button send = (Button) findViewById(R.id.send); //输入框输入内容 final EditText editText = (EditText) findViewById(R.id.edit_text); //适时的让输入框显现或隐藏 danmakuView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (operationLayout.getVisibility() == View.GONE) { operationLayout.setVisibility(View.VISIBLE); 4000 } else { operationLayout.setVisibility(View.GONE); } } }); //发送按钮的点击事件 send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String content = editText.getText().toString(); if (!TextUtils.isEmpty(content)) { //因为是自己的内容,所以传一个true过去,方法内部会判断这个变量 addDanmaku(content, true); //再把输入框置为空 editText.setText(""); } } }); //获取到窗体的顶级父类并设置状态栏的显示隐藏 getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int visibility) { if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) { //显示状态栏,Activity不全屏显示 onWindowFocusChanged(true); } } }); } /** * 向弹幕View中添加一条弹幕 * * @param content 弹幕的具体内容 * @param withBorder 弹幕是否有边框 */ private void addDanmaku(String content, boolean withBorder) { //BaseDanmaku 您可以点击进入查看源码实现 // 弹幕的相关设置:弹幕优先级 颜色 时长 文本 Z轴 Y轴 阴影 描边 // 下划线 内边距 宽度 高度 存活时间 是否是直播弹幕 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()); //显示时长 偏移时间 //如果是true 证明是自己的弹幕,那么就可以更改自己想要的颜色了 if (withBorder) { danmaku.borderColor = Color.GREEN; } //调用底层代码 把弹幕内容添加到LinkedList<Long> mDrawTimes; danmakuView.addDanmaku(danmaku); } /** * 随机生成一些弹幕内容以供测试 */ private void generateSomeDanmaku() { new Thread(new Runnable() { @Override public void run() { while (showDanmaku) { int time = new Random().nextInt(300); String content = "" + time + time; addDanmaku(content, false); try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } /** * sp转px的方法。 */ public int sp2px(float spValue) { final float fontScale = getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } @Override//表示Activity正在停止. protected void onPause() { super.onPause(); //如果弹幕控件不为空 && 弹幕控件的线程还存活 if (danmakuView != null && danmakuView.isPrepared()) { //暂停运行弹幕控件 danmakuView.pause(); } } @Override//表示Activity前台并可与用户交互. protected void onResume() { super.onResume(); if (danmakuView != null && danmakuView.isPrepared() && danmakuView.isPaused()) { danmakuView.resume(); } } @Override//表示Activity即将被销毁. protected void onDestroy() { super.onDestroy(); //把变量置为false showDanmaku = false; //如果弹幕控件还存在.调用release(); 底层调用stop(),并把底层的LinkedList<Long> mDrawTimes 置为空; if (danmakuView != null) { danmakuView.release(); danmakuView = null; } } @Override//都说这个函数才会使用户可以与应用真正开始进行交互. public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); //看了底层后得知 Build.VERSION.SDK_INT == 20 ; if (hasFocus && Build.VERSION.SDK_INT >= 19) { View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility( //这个标志来帮助你的应用维持一个稳定的布局. View.SYSTEM_UI_FLAG_LAYOUT_STABLE //Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION //ctivity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住. | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN //ctivity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住. | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //Activity全屏显示,且状态栏被隐藏覆盖掉. | View.SYSTEM_UI_FLAG_FULLSCREEN //安卓4.4 新增. | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } } }
如上,在安卓设备上,一个简单的弹幕Demo就可以实现了.
项目直达下载通道为: Demo_Danmaku
如有问题请多指正,您的指正使我更正确的前行.
相关文章推荐
- Android安卓最简单的弹幕实现
- 安卓第十天——Progress组件的简单实现
- 关于安卓开始实现最简单地获取系统时间
- Android(安卓)一个简单的聊天界面的实现(eclipse实现)
- 安卓实现简单的发送短信功能
- 安卓开发,实现简单音乐播放器
- 安卓第六天————通讯录的简单实现源码
- 简单实现安卓app自动更新功能
- 用谷歌的AsyncHttpClient简单模仿安卓的AsyncHttpClient,实现异步请求回调函数返回值
- 安卓来电秀简单实现
- 安卓文字滚动简单实现
- 安卓初学者必看实例,(文件管理器简单实现)
- 安卓,采用最简单易懂的方式实现上拉刷新下拉加载更多
- 安卓,采用最简单易懂的方式实现上拉刷新下拉加载更多
- IOS风格的时间选择器在安卓中的简单实现
- 安卓实现gtalk的xmpp简单通信
- 安卓之实现一个简单的短信发送功能
- 安卓平台多语言的简单实现
- 安卓简单实现
- 安卓--第十天--蓝牙app实现与BLE设备简单通信