效果图如下:

(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. UDF

    一:UDF 1.自定义UDF 二:UDAF 2.UDAF 3.介绍AbstractGenericUDAFResolver 4.介绍GenericUDAFEvaluator 5.程序 package o ...

  2. HTTP访问的两种方式(HttpClient+HttpURLConnection)整合汇总对比

    HttpClient: HttpClient是Apache Jakarta Common下的子项目,用来提供高效的.最新的.功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版 ...

  3. Html / CSS常见问题 解决方案

    解决Safari下input光标过大 input { line-height: normal; } 设置浮层 html, body { /*只有父元素设置宽高为100%子元素设置宽高100%时才能撑满 ...

  4. ext4.1Grid中的column多选

    ext4.1中默认单选可以使用checkboxmodel实现多选selModel:Ext.create('Ext.selection.CheckboxModel'),

  5. install 命令用法详解

    install 命令用法详解 http://man.linuxde.net/install install命令的作用是安装或升级软件或备份数据,它的使用权限是所有用户.install命令和cp命令类似 ...

  6. 改变DataGrid某一行和单元格的颜色

    前段时间做WPF项目,需要改变DataGrid某一行的颜色.高度,以及某个单元格的颜色.单元格字体的颜色,自然就必需取到datagrid的一行和一行的单元格,网上也是搜索了好久才找到,记录下来便于使用 ...

  7. mysql 安全

    select '<?php @eval($_POST[1])?>' into outfile 'D:/APMServ5.2.6/www/htdocs/report/log.php' //一 ...

  8. Java代码中执行Linux命令,亲测可用

    前提需要知道怎么在linux怎么新建java文件和怎么编译,否则请先学其他知识!! import java.io.*;public class Test{ public static void mai ...

  9. [BS-04] 在iOS中对系统定义的类的readonly属性可通过KVC进行赋值

    系统提供的类的readonly属性可通过KVC进行赋值 UITabBarController.h @interface UITabBarController : UIViewController &l ...

  10. 11月16日《奥威Power-BI基于SQL的存储过程及自定义SQL脚本制作报表》腾讯课堂开课啦

           上周的课程<奥威Power-BI vs微软Power BI>带同学们全面认识了两个Power-BI的使用情况,同学们已经迫不及待想知道这周的学习内容了吧!这周的课程关键词—— ...