android 图文弹幕重叠,Android双重SurfaceView实现弹幕效果

本文实例为大家分享了Android双重SurfaceView实现弹幕效果的具体代码,供大家参考,具体内容如下

页面布局

首先是XML的layout布局,这里的总的父布局是一个FrameLayout用于贴上两个SurfaceView,一个用来播放视频,一个用来显示弹幕

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context=".DanmuActivity">

android:id="@+id/sv_text"

android:layout_width="match_parent"

android:layout_height="400dp"/>

android:id="@+id/sv_media"

android:layout_width="match_parent"

android:layout_height="400dp"/>

/>

android:id="@+id/et_text"

android:layout_width="300dp"

android:layout_height="wrap_content"

android:layout_marginTop="450dp"/>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="发送"

android:layout_marginTop="500dp"

android:onClick="Gogo"/>

对象类

创建一个对象类来存放你所发送的弹幕

public class Danmu {

String text;//弹幕内容

int x;//x轴

int y;//y轴

public Danmu(String text){

this.text = text;

//将y设置为随机,弹幕出现的位置也为随机

this.y = (int) (Math.random()*400);

this.x = 0;

}

}

Activity实现SurfaceHolder.Callback并重写其方法

先定义需要的东西,播放视频我们用Mediaplayer

//视频播放

private MediaPlayer mediaPlayer;

//弹幕Surface与视频Surface

private SurfaceView sv_text, sv_media;

//两个Surface对应的两个holder

private SurfaceHolder text_holder, media_holder;

EditText editText;//字幕输入框

List list = new ArrayList<>();//存放

初始化MediaPlayer,要在第一步执行否则运行会报空,这里封装成了一个方法,直接在onCreate内调用

private void initPlayer() throws IOException {

//先判断是否创建过,没创建就创建出来

if (mediaPlayer == null) {

mediaPlayer = new MediaPlayer();

}

mediaPlayer.reset();//使其恢复空闲状态

//播放的资源

mediaPlayer.setDataSource("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");

mediaPlayer.prepare();//准备

mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

@Override

public void onPrepared(MediaPlayer mp) {//准备完毕了

mediaPlayer.start();//播放

}

});

}

初始化控件,同样封装为方法,holder用对应的Surface获取到

private void initView() {

sv_text = findViewById(R.id.sv_text);

text_holder = sv_text.getHolder();

text_holder.addCallback(this);

sv_media = findViewById(R.id.sv_media);

media_holder = sv_media.getHolder();

media_holder.addCallback(this);

editText = findViewById(R.id.et_text);

//设置透明,将播放弹幕的Surface放到第一位并设置为背景透明

sv_text.setZOrderOnTop(true);

text_holder.setFormat(PixelFormat.TRANSPARENT);

}

接下来是Surface.Callback重写的方法

@Override

public void surfaceCreated(SurfaceHolder holder) {

//判断当前holder是否是media的那个

if (holder == media_holder) {

//设置要显示的Surfaceholder

mediaPlayer.setDisplay(media_holder);

//判断当前holder是否是字幕的那个

} else if (holder == text_holder) {

//创建线程执行耗时操作

new Thread() {

@Override

public void run() {

super.run();

//死循环用来一直更新弹幕的位置

while (true) {

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

Paint paint = new Paint();//创建画笔

paint.setStrokeWidth(5);//画笔粗细

paint.setColor(Color.GREEN);//画笔颜色

paint.setTextSize(30);//设置文字大小

//创建画板

Canvas canvas = text_holder.lockCanvas();

//判断若画板为空则跳出循环

if (canvas == null) {

break;

}

//设置画布颜色,透明

canvas.drawColor(PixelFormat.TRANSPARENT, PorterDuff.Mode.CLEAR);

//用循环来你的弹幕集合并且在画板上展示出来

//x+=20为你的弹幕在不断的从左到右移动

for (Danmu danmu : list) {

canvas.drawText(danmu.text, danmu.x += 20, danmu.y, paint);

//若移动的位置大于视频Surface的宽度了就归0

if (danmu.x > sv_media.getWidth()) {

danmu.x = 0;

}

}

//将画布解锁并显示到屏幕上

text_holder.unlockCanvasAndPost(canvas);

}

}

}.start();//不要忘记开启线程

}

}

发送的按钮的点击事件

public void Gogo(View view) {

//先判断输入框里有没有东西

if (!editText.getText().toString().isEmpty() && !editText.getText().toString().equals("")) {

Danmu danmu = new Danmu(editText.getText().toString());

list.add(danmu);

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值