SurfaceView
程序员文章站
2022-03-29 19:28:50
...
介绍
使用场景:
播放视频
绘制滚动图形
画板功能
歌词滚动
飞机大战
特点:
频繁的更新UI,内有双缓冲机制
代码
布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".MainActivity">
<SurfaceView
android:id="@+id/surfaceview"
android:layout_above="@id/buttonGroup"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/buttonGroup"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/last"
android:layout_weight="1"
android:onClick="click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="倒退"/>
<Button
android:id="@+id/play"
android:layout_weight="1"
android:onClick="click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="播放"/>
<Button
android:id="@+id/stop"
android:layout_weight="1"
android:onClick="click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止"/>
<Button
android:id="@+id/nest"
android:layout_weight="1"
android:onClick="click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="快进"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
MainActivity::
surfaceview:一个SurfaceView对应一个SurfaceHolder
surfaceholder:持有者,不能直接操作SurfaceView,通过SurfaceHolder控制
画画:paint+canves
new Paint():
setColor();
setStrokeWidth() 画笔宽度(画图)
setTextSize() 文字大小
setAntiAlias(); 抗锯齿 默认false
.
holder.lockCanves() 锁定画布
unlockCanvasAndPost();解除锁定
canves.drawPiont(X,Y,paint)
package com.example.day11;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.SeekBar;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
SurfaceView surfaceView;
MediaPlayer mediaPlayer=new MediaPlayer();
SurfaceHolder surfaceHolder;
SeekBar seekBar;
int isPlay=0;
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what==101) {
Log.i("yu", "设置进度条: "+isPlay);
seekBar.setProgress(isPlay);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar=findViewById(R.id.seekbar);
initvideo();
initplay();
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
int aa=0;
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
aa=i;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
isPlay=aa;
mediaPlayer.seekTo(isPlay);
}
});
}
private void setProgress() {
//视频长度
int max = mediaPlayer.getDuration();
seekBar.setMax(max);
}
private void initplay() {
try {
mediaPlayer.setDataSource("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4");
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
setProgress();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
private void initvideo() {
surfaceView=findViewById(R.id.surfaceview);
surfaceHolder=surfaceView.getHolder();
surfaceHolder.addCallback(this);
}
//创建
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mediaPlayer.setDisplay(surfaceHolder);
}
//改变
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
//销毁
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if (mediaPlayer!=null) {
mediaPlayer.stop();
mediaPlayer.release();//释放资源
mediaPlayer=null;
}
}
public void click(View view) {
switch (view.getId()){
//倒退
case R.id.last:
break;
//播放
case R.id.play:
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
new MyThread().start();
}else if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
break;
//停止
case R.id.stop:
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
break;
//快进
case R.id.nest:
break;
}
}
private class MyThread extends Thread{
@Override
public void run() {
while (mediaPlayer.isPlaying()) {
isPlay = mediaPlayer.getCurrentPosition();
Log.i("yu", "不断读取; "+isPlay);
handler.sendEmptyMessage(101);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
滚动歌词
package com.example.day11_1;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
SurfaceView surfaceView;
SurfaceHolder holder;
int x=0;
int y=100;
int x1=200;
int y1=300;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
surfaceView=findViewById(R.id.surfaceview);
holder=surfaceView.getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
new MyThread().start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
private class MyThread extends Thread{
@Override
public void run() {
Paint paint = new Paint();
paint.setTextSize(50);//字体大小
paint.setStrokeWidth(30); //画笔宽度
paint.setColor(Color.BLUE);//颜色
paint.setAntiAlias(true);//抗锯齿
while (true) {
Canvas canvas = holder.lockCanvas();
if (canvas==null) {
break;
}
if (x==getWindowManager().getDefaultDisplay().getWidth()) {
x=0;
}
if (y1==getWindowManager().getDefaultDisplay().getHeight()) {
y1=0;
}
//擦除之前的
canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);
canvas.drawText("aaa",x+=5,y,paint);
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher),x1,y1+=5,paint);
holder.unlockCanvasAndPost(canvas);
}
}
}
}
上一篇: windows安装mysql5.7
下一篇: windows 安装mysql5.7
推荐阅读
-
android使用surfaceview+MediaPlayer播放视频
-
Cocos2d游戏开发学习记录——1.Surface、SurfaceView、SurfaceHolder实现简单的游戏demo
-
Android SurfaceView拍照录像实现方法
-
Android利用SurfaceView实现简单计时器
-
利用SurfaceView实现下雨与下雪动画效果详解(Kotlin语法)
-
Android SurfaceView拍照录像实现方法
-
利用SurfaceView实现下雨与下雪动画效果详解(Kotlin语法)
-
android图像绘制(四)自定义一个SurfaceView控件
-
Android截屏SurfaceView黑屏问题的解决办法
-
Android利用SurfaceView实现下雨的天气动画效果