效果图如下:
(PS本来是要给大家穿gif动态图的,无奈太大了,没法上传)
功能实现:暂停,播放,快进,快退,全屏,退出全屏,等基本功能
实现的思路:
在主布局中放置一个SurfaceView,在SurfaceView中放置一个MediaPlayer ,在其下方自定义一个MediaController,不过也不能称之为MediaController,使用的是PupupWindow来实现的,在PupupWindow布局中放置几个textView,Button,最重要的使我们的SeekBar控件,创建一个定时器,当用户触摸屏幕时,让其popupWindow显示5秒的时间,具体实现可以看代码(主程序的代码有点多,耐心点看啊)
主布局activity_main.xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" > <SurfaceView
android:layout_width="match_parent"
android:layout_height="260dp"
android:id="@+id/surfaceView_main"
/> <ImageView
android:onClick="clickButton"
android:id="@+id/imageView_main_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:src="@drawable/ic_launcher" /> </RelativeLayout>
popupwindow.xml的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/bottom_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:orientation="horizontal"
android:background="@drawable/voip_toast_bg"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:weightSum="10" > <ImageView
android:id="@+id/imageView_play"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:src="@drawable/video_btn_on" /> <SeekBar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5.0"
android:max="100"
android:maxHeight="5dp"
android:minHeight="5dp"
android:layout_marginLeft="5dp"
android:progress="0"
android:thumbOffset="0dp" /> <TextView
android:id="@+id/textView_playtime"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.3"
android:gravity="center"
android:text="00:00"
android:textColor="@android:color/white"
android:textSize="12sp" /> <TextView
android:id="@+id/textView_playtime"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:gravity="center"
android:text="/"
android:textColor="@android:color/white"
android:textSize="12sp" /> <TextView
android:id="@+id/textView_totaltime"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.3"
android:gravity="center"
android:text="00:00"
android:textColor="@android:color/white"
android:textSize="12sp" /> <ImageView
android:id="@+id/imageView_fullscreen"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:src="@drawable/video_full_screen" /> </LinearLayout>
主Activity中的代码:
package com.amy.day43_03_SurfaceViewMediaPlayer; import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask; import android.R.integer;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.PopupWindow;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView; public class MainActivity extends Activity {
private final static String TAG = "MainActivity";
private Context mContext = this;
private SurfaceView surfaceView = null;
private SurfaceHolder surfaceHolder = null;
private MediaPlayer mediaPlayer = null;
private ImageView imageView_main_show = null; // 自定义的控制条及其上的控件
private View controllerView;
private PopupWindow popupWindow; private ImageView imageView_play;
private ImageView imageView_fullscreen;
private SeekBar seekBar;
private TextView textView_playTime;
private TextView textView_duration;
private String filePath = null; private float densityRatio = 1.0f; // 密度比值系数(密度比值:一英寸中像素点除以160) private Runnable r = new Runnable() {
@Override
public void run() {
// 又回到了主线程
showOrHiddenController();
}
}; private MyVideoBroadcastReceiver receiver = null; // 设置定时器
private Timer timer = null;
private final static int WHAT = 0;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case WHAT:
if (mediaPlayer != null) {
int currentPlayer = mediaPlayer.getCurrentPosition();
if (currentPlayer > 0) {
mediaPlayer.getCurrentPosition();
textView_playTime.setText(formatTime(currentPlayer)); // 让seekBar也跟随改变
int progress = (int) ((currentPlayer / (float) mediaPlayer
.getDuration()) * 100); seekBar.setProgress(progress);
} else {
textView_playTime.setText("00:00");
seekBar.setProgress(0);
}
} break; default:
break;
}
};
}; // 自动隐藏自定义播放器控制条的时间
private static final int HIDDEN_TIME = 5000; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView(); initMediaPlayer(); initController(); // 动态注册广播接受者
receiver = new MyVideoBroadcastReceiver();
registerReceiver(receiver, new IntentFilter(
"com.amy.day43_03_SurfaceViewMediaPlayer"));
} private String formatTime(long time) {
SimpleDateFormat formatter = new SimpleDateFormat("mm:ss");
return formatter.format(new Date(time));
} private void initController() { controllerView = getLayoutInflater().inflate(
R.layout.popupwindow_mediacontroller, null); // 初始化popopWindow
popupWindow = new PopupWindow(controllerView,
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true); imageView_play = (ImageView) controllerView
.findViewById(R.id.imageView_play);
imageView_fullscreen = (ImageView) controllerView
.findViewById(R.id.imageView_fullscreen); seekBar = (SeekBar) controllerView.findViewById(R.id.seekbar); textView_playTime = (TextView) controllerView
.findViewById(R.id.textView_playtime);
textView_duration = (TextView) controllerView
.findViewById(R.id.textView_totaltime); seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { // 表示手指拖动seekbar完毕,手指离开屏幕会触发以下方法
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 让计时器延时执行
handler.postDelayed(r, HIDDEN_TIME);
} // 在手指正在拖动seekBar,而手指未离开屏幕触发的方法
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 让计时器取消计时
handler.removeCallbacks(r);
} @Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
int playtime = progress * mediaPlayer.getDuration() / 100;
mediaPlayer.seekTo(playtime);
} }
}); // 点击播放的时候,判断是播放还是暂停
imageView_play.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
if (imageView_main_show.getVisibility() == View.VISIBLE) {
imageView_main_show.setVisibility(View.GONE);
} if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
imageView_play.setImageResource(R.drawable.video_btn_down);
} else {
mediaPlayer.start();
imageView_play.setImageResource(R.drawable.video_btn_on); } }
}); // 实现全屏和退出全屏(内容物横竖屏,不是屏幕的横竖屏)
imageView_fullscreen.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
imageView_fullscreen
.setImageResource(R.drawable.video_full_screen); // 重新设置surfaceView的高度和宽度
surfaceView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
surfaceView.getLayoutParams().height = (int) (260 * densityRatio);
} else if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
imageView_fullscreen
.setImageResource(R.drawable.video_inner_screen); surfaceView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
surfaceView.getLayoutParams().height = LayoutParams.MATCH_PARENT;
} surfaceView.setLayoutParams(surfaceView.getLayoutParams());
}
});
} private void showOrHiddenController() {
if (popupWindow.isShowing()) {
popupWindow.dismiss();
} else {
// 将dp转换为px
int controllerHeightPixel = (int) (densityRatio * 50);
popupWindow.showAsDropDown(surfaceView, 0, -controllerHeightPixel);
// 延时执行
handler.postDelayed(r, HIDDEN_TIME);
}
} private void initMediaPlayer() {
filePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()
+ File.separator + "myabc.mp4"; Log.i("==main==",
"==========="
+ Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath());
if (mediaPlayer == null) {
// 1,创建MediaPlay对象
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare();
// mediaPlayer.start();
mediaPlayer.setLooping(false);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} } mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override
public void onPrepared(MediaPlayer mp) {
// 表示准备完成,设置总的时长,使用时间格式化工具 // String duration = mediaPlayer.getDuration() ;
textView_duration.setText(formatTime(mediaPlayer.getDuration()));
// 初始化定时器
timer = new Timer();
timer.schedule(new TimerTask() { @Override
public void run() {
handler.sendEmptyMessage(WHAT);
}
}, 0, 1000);
}
}); mediaPlayer.setOnErrorListener(new OnErrorListener() { @Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset(); return false;
}
}); mediaPlayer.setOnCompletionListener(new OnCompletionListener() { @Override
public void onCompletion(MediaPlayer mp) {
// 发送广播,播放下一首歌曲 Intent intent = new Intent();
intent.setAction("com.amy.day43_03_SurfaceViewMediaPlayer");
sendBroadcast(intent);
}
});
} private void initView() {
// TODO Auto-generated method stub
densityRatio = getResources().getDisplayMetrics().density; // 表示获取真正的密度 imageView_main_show = (ImageView) findViewById(R.id.imageView_main_play);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView_main);
surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(new Callback() { @Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
} @Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mediaPlayer != null) { mediaPlayer.setDisplay(surfaceHolder);
// mediaPlayer.start() ; } } @Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
// TODO Auto-generated method stub }
}); // 设置屏幕的触摸监听
surfaceView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
// 表示在点击的瞬间就显示控制条
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
showOrHiddenController();
break; default:
break;
}
return true;
}
});
} /**
* 设置控件的监听事件
*
* @param v
*/
public void clickButton(View v) {
switch (v.getId()) {
case R.id.imageView_main_play: imageView_main_show.setVisibility(View.GONE);
mediaPlayer.start(); break; default:
break;
}
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy(); unregisterReceiver(receiver);
timer.cancel(); if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
} handler.removeCallbacksAndMessages(null);
} class MyVideoBroadcastReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
"com.amy.day43_03_SurfaceViewMediaPlayer")) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.ic_launcher)
.setTitle("提示")
.setMessage("视屏播放完毕,是否播放")
.setNegativeButton("取消", null)
.setPositiveButton("确定",
new DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog,
int which) {
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepare();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaPlayer.setLooping(false); mediaPlayer.start();
}
}).show(); }
} } }