基于SurfaceView创建手机xml动态背景

本文介绍如何使用SurfaceView作为背景播放视频。通过自定义MySurfaceView类,实现了不同类型的视频资源加载与播放,包括本地、网络及在线视频。文章提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

surfaceView通俗的讲就类似与给手机的那层薄膜,在那层薄膜上你可以绘制各种图画甚至动画,我写了一个关于利用surfaceView铺设了一个“膜”,在使用MediaPlayer调用播放短视频来实现背景为动态背景的效果,话不多说直接进入代码之中:

新建一个java类,用于设置这层“薄膜”,起名为MySurfaceView继承SurfaceView类:

package com.sq.test_video;

import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;

/**
 * Created by sq-kevin on 2017/8/30 0030.
 */

public class MySurfaceView extends SurfaceView implements
        SurfaceHolder.Callback, MediaPlayer.OnErrorListener,
        MediaPlayer.OnCompletionListener, MediaPlayer.OnInfoListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnSeekCompleteListener,
        MediaPlayer.OnVideoSizeChangedListener {

    private Context context;
    private SurfaceHolder surfaceHolder;
    private MediaPlayer player;
    private int progressValue = 0;
    private Uri uri;

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        player.setDisplay(surfaceHolder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        player.setDisplay(holder);
        playVideo();
    }

    /**
     * 播放视频
     */
    public void playVideo() {
        switch (TYPE){
            case ONLINE:
                playOnline();
                break;
            case LOCAL:
                playLocation();
                break;
            case NETWORK:
                playNetWork();
                break;
        }
    }

    /**
     * 播放HTTP视频
     */
    private void playNetWork() {
        try {
            initPlayer();
            player.setDataSource(context,uri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.prepareAsync();
    }

    /**
     * 播放本地视频
     */
    private void playLocation() {
        try {
            initPlayer();
            player.setDataSource(context,uri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.prepareAsync();
    }

    /**
     * 播放在线视频 rtsp协议
     */
    private void playOnline() {
        try {
            initPlayer();
            player.setDataSource(context,uri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.prepareAsync();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (player.isPlaying()){
            progressValue = player.getCurrentPosition();
            player.stop();
        }else {
            player.stop();
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        switch (what){
            case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
                break;
            case MediaPlayer.MEDIA_ERROR_UNKNOWN:
                break;
            default:
                break;
        }
        return true;
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        player.start();
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        // 当一些特定信息出现或者警告时触发
        switch (what){
            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                break;
            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                break;
            case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
                break;
            case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
                break;
            case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
                break;
            case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
                break;
        }
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        if (!mp.isPlaying()){
            mp.start();
        }
    }

    @Override
    public void onSeekComplete(MediaPlayer mp) {

    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {

    }

    /**
     * 枚举视频地址的类型
     */
    public enum URITYPE{
        LOCAL,NETWORK,ONLINE
    }

    /**
     * 视频地址类型
     */
    private URITYPE TYPE;

    public MySurfaceView(Context context) {
        this(context,null);
    }

    public MySurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initView();
    }

    private void initView() {
        initPlayer();
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(this);
    }

    private void initPlayer() {
        if (player == null){
            player = new MediaPlayer();
        }
        player.reset();
        player.setOnErrorListener(this);
        player.setOnCompletionListener(this);
        player.setOnInfoListener(this);
        player.setOnPreparedListener(this);
        player.setOnSeekCompleteListener(this);
        player.setOnVideoSizeChangedListener(this);
    }

    /**
     * 暂停播放
     */
    public void pause(){
        progressValue = player.getCurrentPosition();
        player.pause();
    }

    /**
     * 继续播放
     */
    public void resume(){
        if (!player.isPlaying()){
            player.seekTo(progressValue);
            player.start();
        }
    }

    /**
     * 停止播放
     */
    public void stop(){
        progressValue = 0;
        if (player.isPlaying()){
            player.seekTo(0);
            player.pause();
        }else {
            player.pause();
        }
    }

    /**
     * 重播
     */
    public void reset(){
        progressValue = 0;
        if (player.isPlaying()){
            player.seekTo(0);
            player.start();
        }else {
            playVideo();
        }
    }

    public void setUriAddress(Uri uriAddress){
        uri = uriAddress;
        TYPE = URITYPE.LOCAL;
    }

}

对外提供setUriAddress方法,来设置视频来源:

    public void setUriAddress(Uri uriAddress){
        uri = uriAddress;
        TYPE = URITYPE.LOCAL;
    }

initPlayer()方法是对mediaPlayer做初始化操作,并设置接口监听事件,我只写下了部分作一个小示范:

 private void initPlayer() {
        if (player == null){
            player = new MediaPlayer();
        }
        player.reset();
        player.setOnErrorListener(this);
        player.setOnCompletionListener(this);
        player.setOnInfoListener(this);
        player.setOnPreparedListener(this);
        player.setOnSeekCompleteListener(this);
        player.setOnVideoSizeChangedListener(this);
    }

播放视频来源有三种,网络本地在线:

 /**
     * 播放HTTP视频
     */
    private void playNetWork() {
        try {
            initPlayer();
            player.setDataSource(context,uri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.prepareAsync();
    }

    /**
     * 播放本地视频
     */
    private void playLocation() {
        try {
            initPlayer();
            player.setDataSource(context,uri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.prepareAsync();
    }

    /**
     * 播放在线视频 rtsp协议
     */
    private void playOnline() {
        try {
            initPlayer();
            player.setDataSource(context,uri);
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.prepareAsync();
    }

surfaceView被继承后复写的三个方法:

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        player.setDisplay(surfaceHolder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        player.setDisplay(holder);
        playVideo();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (player.isPlaying()){
            progressValue = player.getCurrentPosition();
            player.stop();
        }else {
            player.stop();
        }
    }

将MySurfaceView写好后铺设到xml文件充当背景,如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.sq.test_video.MainActivity">

    <com.sq.test_video.MySurfaceView
        android:id="@+id/lalala"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

之后在activity中绑定MySurfaceView的id,然后在设置uri就能运行啦~~

public class MainActivity extends AppCompatActivity {

    private MySurfaceView mySurfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mySurfaceView = (MySurfaceView) findViewById(R.id.lalala);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }

        Uri uri = Uri.parse("android.resource://" + getPackageName()
         +  "/" + R.raw.video);

        mySurfaceView.setUriAddress(uri);
        mySurfaceView.playVideo();
    }
}


最后显示效果就是这样子的啊~因为上传不了短视频,所以就截了几张图片代替啦~



源码下载请点击此处.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值