弹幕Demo

在程序开发中,弹幕用的最多的地方就是直播平台,例如常见的斗鱼。在观看视频直播时,通常在屏幕底部会有一个输入框,专门用于输入屏幕。弹幕其实很像人们发送的即时消息,只不过是显示在直播界面上。

弹幕程序

任务综述
弹幕界面注意显示视频播放、弹幕文本信息、弹幕输入框以及弹幕的“发送”按钮,当点击弹幕界面上的任意地方时,界面底部会弹出一个输入框和一个“发送”按钮,此时可以输入文字并发送。当再次单击弹幕界面上的任意地方时,界面底部的输入框和“发送”按钮便会消失。为了与他人发送的弹幕有所区别,本机发送的弹幕会添加一个蓝色的边框。

1. 弹幕界面

任务分析:
弹幕界面主要显示视频播放、弹幕文本信息、弹幕输入框以及弹幕的“发送”按钮,界面效果如图所示。

10186693-08280d5c13fdc682.png
弹幕界面

任务实施:
(1)创建项目:Barrage。

(2)导入视频文件。在程序的res中创建raw目录,将视频文件sun.mp4导入该目录。

(3)添加DanmakuFlamMaster库。由于弹幕界面中用到了DanmakuFlameMaster库,因此将其库导入本项目中。在AS中,右键选择Open Module Settings选项然后选择Dependencies选项卡,单击“+”选择Library dependency,把com.github.ctiao:DanmakuFlameMaster:0.5.3库加入项目。

注意:
如果Library dependency选项中找不到该库,则可以直接在该项目的build.gradle文件中添加如下代码。

compile 'com.github.ctiao:DanmakuFlameMaster:0.5.3'

(4)放置界面控件。
一个VideoView控件用于播放视频,
一个DanmakuView控件用于显示弹幕,
一个EditText控件用于输入弹幕文本,
一个Button控件用于显示发送弹幕的按钮。

activity_main.xml

<?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/videoview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
    <master.flame.danmaku.ui.widget.DanmakuView
        android:id="@+id/danmaku"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <LinearLayout
        android:id="@+id/ly_send"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:background="#fff"
        android:visibility="gone">
        <EditText
            android:id="@+id/et_text"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />
        <Button
            android:id="@+id/btn_send"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:text="发送" />
    </LinearLayout>
</RelativeLayout>

2. 弹幕界面逻辑代码

任务分析:
当点击弹幕界面时,界面底部会弹出一个输入框和一个“发送”按钮,当输入文字并点击“发送”按钮后,弹幕会出现一个蓝色框,框中显示刚刚发送的文字;当再次点击弹幕界面时,界面底部的输入框和“发送”按钮消失。

(1)获取界面控件。创建initView()方法,用于获取弹幕界面上所要用到的控件。
(2)播放视频。在MainActivity中创建一个playVideo()方法,在该方法中获取res/raw文件夹中的sun.mp4视频文件的uri,并调用色图VideoURI()方法设置uri,然后调用start()方法播放视频。
(3)初始化弹幕。创建一个initDanmaku()方法,用于初始化弹幕并调用弹幕的随机生成与添加方法。
(4)随机生成有添加弹幕。创建generateDanmakus()与addDanmaku()方法,分别用于随机生成弹幕文字与添加弹幕到屏幕上。

MainActivity.xml

public class MainActivity extends AppCompatActivity {
    private boolean showDanmaku;
    private DanmakuView danmakuView;
    private DanmakuContext danmakuContext;
    private Button sendButton;
    private LinearLayout sendLayout;
    private EditText editText;
    private VideoView videoView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        playVideo();
        initDanmaku();
    }
    /**
     * 初始化界面控件
     */
    private void initView() {
        videoView = (VideoView) findViewById(R.id.videoview);
        sendLayout = (LinearLayout) findViewById(R.id.ly_send);
        sendButton = (Button) findViewById(R.id.btn_send);
        editText = (EditText) findViewById(R.id.et_text);
        danmakuView = (DanmakuView) findViewById(R.id.danmaku);
    }
    /**
     * 播放视频
     */
    private void playVideo() {
        String uri = "android.resource://" + getPackageName() + "/" + R.raw.sun;
        if (uri != null) {
            videoView.setVideoURI(Uri.parse(uri));
            videoView.start();
        } else {
            videoView.getBackground().setAlpha(0);//将背景设为透明
        }
    }
    /**
     * 创建弹幕解析器
     */
    private BaseDanmakuParser parser = new BaseDanmakuParser() {
        @Override
        protected IDanmakus parse() {
            return new Danmakus();
        }
    };
    /**
     * 初始化弹幕
     */
    private void initDanmaku() {
        danmakuView.setCallback(new DrawHandler.Callback() {//设置回调函数
            @Override
            public void prepared() {
                showDanmaku = true;
                danmakuView.start(); //开始弹幕
                generateDanmakus();  //调用随机生成弹幕方法
            }
            @Override
            public void updateTimer(DanmakuTimer timer) {
            }
            @Override
            public void danmakuShown(BaseDanmaku danmaku) {
            }
            @Override
            public void drawingFinished() {
            }
        });
        danmakuContext = DanmakuContext.create();
        danmakuView.enableDanmakuDrawingCache(true);//提升屏幕绘制效率
        danmakuView.prepare(parser, danmakuContext);//进行弹幕准备
        //为danmakuView设置点击事件
        danmakuView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (sendLayout.getVisibility() == View.GONE) {
                    sendLayout.setVisibility(View.VISIBLE);//显示布局
                } else {
                    sendLayout.setVisibility(View.GONE);   //隐藏布局
                }
            }
        });
        //为发送按钮设置点击事件
        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String content = editText.getText().toString();
                if (!TextUtils.isEmpty(content)) {
                    addDanmaku(content, true);//添加一条弹幕
                    editText.setText("");
                }
            }
        });
    }
    /**
     * 添加一条弹幕
     *
     * @param content    弹幕的具体内容
     * @param border     弹幕是否有边框
     */
    private void addDanmaku(String content, boolean border) {
        //创建弹幕对象,TYPE_SCROLL_RL表示从右向左滚动的弹幕
        BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(
                BaseDanmaku.TYPE_SCROLL_RL);
        danmaku.text = content;
        danmaku.padding = 6;
        danmaku.textSize = 30;
        danmaku.textColor = Color.WHITE;//弹幕文字的颜色
        danmaku.setTime(danmakuView.getCurrentTime());
        if (border) {
            danmaku.borderColor = Color.BLUE;//弹幕文字边框的颜色
        }
        danmakuView.addDanmaku(danmaku);     //添加一条弹幕
    }
    /**
     * 随机生成一些弹幕内容
     */
    private void generateDanmakus() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (showDanmaku) {
                    int num = new Random().nextInt(300);
                    String content = "" + num;
                    addDanmaku(content, false);
                    try {
                        Thread.sleep(num);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
    @Override
    protected void onPause() {
        super.onPause();
        if (danmakuView != null && danmakuView.isPrepared()) {
            danmakuView.pause();
        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        if (danmakuView != null && danmakuView.isPrepared() &&
                danmakuView.isPaused()) {
            danmakuView.resume();
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        showDanmaku = false;
        if (danmakuView != null) {
            danmakuView.release();
            danmakuView = null;
        }
    }
}

(5)修改清单文件。由于在项目中需要使用自己的图标,并且在项目创建时默认带有的标题栏不够美观,因此需要修改清单文件中<application>标签中的icon与theme属性。

        android:icon="@mipmap/barrage_icon"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"

由于只有视频播放界面处于横屏时视频与弹幕才会更加清晰,因此需要设置MainActivity对应的<activity>标签中的screenOrientation属性为横屏。

 <activity android:name=".MainActivity" 
android:screenOrientation="landscape">

猜你喜欢

转载自blog.csdn.net/weixin_34116110/article/details/87420204