效果图如下:

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

  

Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器的更多相关文章

  1. android中使用surfaceview+MediaPlayer播放视频

    Android中播放视频主要有两种方式: 使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型 使用android自带的VideoView,这种方法 ...

  2. android下面使用SurfaceView+ mediaPlayer播放视频

    final SurfaceView surfaceView = new SurfaceView(StartupActivity.this); StartupActivity.this.mediaPla ...

  3. 【Android】利用安卓的数据接口、多媒体处理编写内存卡Mp3播放器app

    通过调用安卓的MediaPlayer能够直接完毕Mp3等主流音频的播放,同一时候利用ContentResolver与Cursor能够直接读取安卓内在数据库的信息.直接获取当前sdcard中全部音频的列 ...

  4. Android中使用SurfaceView和Canvas来绘制动画

    事实上每一个View中都有Canvas能够用来绘制动画.仅仅须要在这个View中重载onDraw()方法就能够,可是SurfaceView类是一个专门用来制动动画的类. Canvas(中文叫做&quo ...

  5. Android中surface,surfaceview,sufaceholder以及surface客户端的关系

    这里以照相机camera功能的实现来解释surface,surfaceview,sufaceholder以及surface客户端(本例子中指的是camera)的关系,surface及其client(客 ...

  6. 【Android 应用开发】Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

    . 参考界面 : 携程app首页的广告栏, 使用ViewPager实现        自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...

  7. Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题

    . 参考界面 : 携程app首页的广告栏, 使用ViewPager实现        自制页面效果图 : 源码下载地址: http://download.csdn.net/detail/han1202 ...

  8. Android视屏播放兼容性问题分享

    最近产品提了一个紧急需求:webview加载的URL,需要支持视频播放. 为了快速完成需求,功能实现上直接使用系统自带播放器播放视频.由于是自带播放器,需要进行兼容性测试,过程发现了不少问题,这里分享 ...

  9. android中VideoView播放sd卡上面的视频

    (1)videoView组件只支持MP4和3gp格式的视屏播放,如果想播放其它视屏格式的文件,还得开发能够播放的视屏播放器 (2)videoView组件功能比较单一,如果想开发功能丰富的播放器,还得重 ...

随机推荐

  1. 【C51】单片机中断

    引言 其实人的一生和单片机的运行很类似.就拿人的一生来说:有些事只需要做一次,比如得了水痘以后,体内产生免疫,以后就不会再生这个病了.有些事需要反复做,比如反复读书,反复工作,反复与困苦打交道,反复地 ...

  2. An Implementation of Double-Array Trie

    Contents What is Trie? What Does It Take to Implement a Trie? Tripple-Array Trie Double-Array Trie S ...

  3. linux与linux,linux与windows之间用SSH传输文件

    linux与linux,linux与windows之间用SSH传输文件linux与linux之间传送文件:scp file username@hostIP:文件地址    例: scp abc.txt ...

  4. [LeetCode]题解(python):086 - Partition List

    题目来源 https://leetcode.com/problems/partition-list/ Given a linked list and a value x, partition it s ...

  5. [LeetCode]题解(python):083 - Remove Duplicates from Sorted List

    题目来源 https://leetcode.com/problems/remove-duplicates-from-sorted-list/ Given a sorted linked list, d ...

  6. [LeetCode]题解(python):081 - Search in Rotated Sorted Array II

    题目来源 https://leetcode.com/problems/search-in-rotated-sorted-array-ii/ Follow up for "Search in ...

  7. C# RichTextBox 滚动条 滚动到最后一行

    使用RichTextBox控件用于显示数据时,滚动条只停留在开头,而我希望能够一直更新,显示最后一行的内容.解决方法记录于此. 转载自以下链接: http://blog.csdn.net/xelone ...

  8. 如何在 Linux 中清除缓存(Cache)

              如何在 Linux 中清除缓存(Cache)            方法一: http://mp.weixin.qq.com/s?__biz=MjM5ODAzODgyMQ==&am ...

  9. jq的核心基础

    1.jq代码的风格    jq对象$().css();jQuery().css();  //获取jquery对象 示例$().css('background':'red').css('font-siz ...

  10. openni2 和opencv读取数据

    http://blog.csdn.net/aptx704610875/article/details/49585241