一个Activity主要用来做播放视频使用,并且是全屏播放的话,主要采用横屏(Landscape orientation 显示宽度大于高度)显示视频,那么可以指定Activity的属性android:screenOrientation="landscape"让Activity在设备上以横屏显示。
本文使用VideoView来显示视屏,Potrait(竖屏)时布局样式中宽匹配父布局,高匹配内容;Landscape(横屏)时布局样式中宽匹配内容,高匹配布局。视屏播放中,用户调正设备方向时,导致屏幕方向发生变化,视屏能够适应布局样式显示视频,并正常继续播放。
示例图:
1. 构建布局
Potrait: res/layout/activity_videoview.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <VideoView android:id="@+id/videoView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="5dp"/> </LinearLayout>
Landscape: res/layout-land/activity_videoview.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <VideoView android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/videoView" android:layout_gravity="center_horizontal" android:layout_margin="5dp"/> </LinearLayout>
2.创建Activity
package secondriver.sdk.activity;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;
import secondriver.sdk.R;
/**
* Author : secondriver
* Created : 2015/11/30
*/
public class VideoViewActivity extends Activity implements
MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
private final String TAG = VideoViewActivity.class.getName();
public VideoView videoView;
public MediaController mediaController;
public int videoPosition = 0;
public ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videoview);
dialog = new ProgressDialog(this);
dialog.setTitle("视屏播放器");
dialog.setMessage("正在加载...");
dialog.setCancelable(false);
mediaController = new MediaController(this);
videoView = (VideoView) findViewById(R.id.videoView);
videoView.setMediaController(mediaController);
videoView.setOnCompletionListener(this);
videoView.setOnPreparedListener(this);
videoView.setOnErrorListener(this);
}
private void loadVideo() {
Log.d(TAG, "load video");
dialog.show();
try {
videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bsg));
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
@Override
protected void onStart() {
Log.d(TAG, "onStart");
super.onStart();
loadVideo();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
Log.d(TAG, "onConfigurationChanged");
super.onConfigurationChanged(newConfig);
}
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(TAG, "Media onCompletion");
Toast.makeText(VideoViewActivity.this, "播放完成", Toast.LENGTH_LONG).show();
mp.release();
}
@Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "Media onPrepared");
if (dialog.isShowing()) {
dialog.dismiss();
}
mp.seekTo(videoPosition);
if (videoPosition == 0) {
mp.start();
} else {
mp.pause();
}
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d(TAG, "Media onError");
String err = "未知错误";
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
err = "媒体服务终止";
break;
default:
break;
}
Toast.makeText(VideoViewActivity.this, err, Toast.LENGTH_LONG).show();
return true;
}
}
3. 设置Activity属性
<activity android:name=".activity.VideoViewActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
/>
代码中重写了onConfigurationChanged,可以在此处做配置发生变化的处理。
在运行时发生配置更改,Activity被关闭,默认情况下重新启动,但在设置了Activity的configChanges属性的配置将防止活动被重新启动,Activity仍在运行并且onConfigurationChanged方法被调用。
需要注意的是如果应用程序的target API level是13+的话(声明了minSdkversion和targetSdkVersion属性),需要同时设置screensize, 因为设备的横竖方向发生变化的时候,当前屏幕的可用尺寸也将发生变化。