Android Double SurfaceView to achieve barrage effect
- 2021-11-14 06:59:21
- OfStack
In this paper, we share the specific code of Android double SurfaceView barrage effect for your reference. The specific contents are as follows
Page layout
The first is the layout layout of XML. The general parent layout here is one FrameLayout for pasting two SurfaceView, one for playing video and one for displaying barrage
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
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">
<SurfaceView
android:id="@+id/sv_text"
android:layout_width="match_parent"
android:layout_height="400dp"/>
<SurfaceView
android:id="@+id/sv_media"
android:layout_width="match_parent"
android:layout_height="400dp"/>
/>
<EditText
android:id="@+id/et_text"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginTop="450dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Send "
android:layout_marginTop="500dp"
android:onClick="Gogo"/>
</FrameLayout>
Object class
Create an object class to store the barrage you send
public class Danmu {
String text;// Barrage content
int x;//x Shaft
int y;//y Shaft
public Danmu(String text){
this.text = text;
// Will y Set to random , The location of the barrage is also random
this.y = (int) (Math.random()*400);
this.x = 0;
}
}
Activity implements SurfaceHolder. Callback and overrides its methods
First define what you need, and play the video. We use Mediaplayer
// Video playback
private MediaPlayer mediaPlayer;
// Barrage Surface And video Surface
private SurfaceView sv_text, sv_media;
// Two Surface Corresponding two holder
private SurfaceHolder text_holder, media_holder;
EditText editText;// Subtitle input box
List<Danmu> list = new ArrayList<>();// Storage
Initialize MediaPlayer, if you want to execute it in step 1, otherwise it will report empty. Here, it is encapsulated as a method, which is called directly in onCreate
private void initPlayer() throws IOException {
// First determine whether it has been created , Create it without creating it
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
}
mediaPlayer.reset();// Restore it to its idle state
// Played resources
mediaPlayer.setDataSource("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
mediaPlayer.prepare();// Prepare
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {// It's ready
mediaPlayer.start();// Play
}
});
}
Initialize the control, which is also encapsulated as a method. holder is obtained by the corresponding 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);
// Setting Transparency , The that will play the barrage Surface Put it in the first place 1 Bit and set to background transparency
sv_text.setZOrderOnTop(true);
text_holder.setFormat(PixelFormat.TRANSPARENT);
}
Next is the Surface. Callback override method
@Override
public void surfaceCreated(SurfaceHolder holder) {
// Judge the current holder Whether it is media The one of
if (holder == media_holder) {
// To set the Surfaceholder
mediaPlayer.setDisplay(media_holder);
// Judge the current holder Is it the one with subtitles
} else if (holder == text_holder) {
// Create a thread to perform a time-consuming operation
new Thread() {
@Override
public void run() {
super.run();
// An infinite loop is used 1 Update the location of the barrage directly
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Paint paint = new Paint();// Create a brush
paint.setStrokeWidth(5);// Brush thickness
paint.setColor(Color.GREEN);// Brush color
paint.setTextSize(30);// Set the text size
// Create Sketchpad
Canvas canvas = text_holder.lockCanvas();
// Judge that if the drawing board is empty, jump out of the loop
if (canvas == null) {
break;
}
// Set Canvas Color , Transparency
canvas.drawColor(PixelFormat.TRANSPARENT, PorterDuff.Mode.CLEAR);
// Loop your barrage collection and show it on the drawing board
//x+=20 For your barrage is constantly moving from left to right
for (Danmu danmu : list) {
canvas.drawText(danmu.text, danmu.x += 20, danmu.y, paint);
// If the moving position is larger than the video Surface The width of the return 0
if (danmu.x > sv_media.getWidth()) {
danmu.x = 0;
}
}
// Unlock the canvas and display it on the screen
text_holder.unlockCanvasAndPost(canvas);
}
}
}.start();// Don't forget to open the thread
}
}
Click event of the button sent
public void Gogo(View view) {
// First judge if there is anything in the input box
if (!editText.getText().toString().isEmpty() && !editText.getText().toString().equals("")) {
Danmu danmu = new Danmu(editText.getText().toString());
list.add(danmu);
}
}