您的位置:首页 > 移动开发 > Android开发

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

2017-09-02 18:36 323 查看
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">

<
ad1c
;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();
}
}


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







源码下载请点击此处.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息