参看:Android自定义视频播放器(一):
https://blog.csdn.net/zxd1435513775/article/details/81507909
<https://blog.csdn.net/zxd1435513775/article/details/81507909>
参看:Android自定义视频播放器(二):
https://blog.csdn.net/zxd1435513775/article/details/81533053
<https://blog.csdn.net/zxd1435513775/article/details/81533053>

一、引言

在上文中,我们通过自定义控制面板的布局,来实现自定义的播放控制,下面来对里面的各个组件进行事件绑定。
@Override public void onClick(View v) { if ( v == btnVoice ) { //声音按钮,处理声音
isMute = !isMute; updataVoice(currentVoice, isMute); } else if ( v ==
btnSwichPlayer ) { // Handle clicks for btnSwichPlayer } else if ( v == btnExit
) { // Handle clicks for btnExit } else if ( v == btnVideoPre ) { // Handle
clicks for btnVideoPre } else if ( v == btnVideoStartPause ) { //播放和暂停按钮
startAndPause(); } else if ( v == btnVideoNext ) { // Handle clicks for
btnVideoNext } else if ( v == btnVideoSiwchScreen ) { // Handle clicks for
btnVideoSiwchScreen } }
二、播放按钮和播放进度条SeekBar事件绑定

1、播放/暂停按钮事件
//播放和暂停视频 private void startAndPause() { if (videoView.isPlaying()) {
//视频在播放-设置暂停 videoView.pause(); //按钮状态设置播放
btnVideoStartPause.setBackgroundResource(R.drawable.btn_video_start_selector);
} else { //视频播放 videoView.start(); //按钮状态设置暂停
btnVideoStartPause.setBackgroundResource(R.drawable.btn_video_pause_selector);
} }
2、播放视频进度条事件
(1)为VideoView设置的监听 //设置视频准备好了的监听 videoView.setOnPreparedListener(new
MyPreparedListener()); //设置视频播放出错的监听 videoView.setOnErrorListener(new
MyErrorListener()); //设置视频播放完成的监听 videoView.setOnCompletionListener(new
MyCompletionListener()); (2)当视频准备好了,在该监听器中,为SeekBar的总长赋值,并且发送handler private
class MyPreparedListener implements MediaPlayer.OnPreparedListener { @Override
public void onPrepared(MediaPlayer mediaPlayer) { //视频准备好了,进行播放
mediaPlayer.start(); //视频的总时长,并关联SeekBar的总长度 int duration =
videoView.getDuration(); //设置SeekBar进度的总长 seekbarVideo.setMax(duration);
//设置视频的总时间 tvDuration.setText(utils.stringForTime(duration)); //发消息
handler.sendEmptyMessage(PROGRESS); } } (3)处理handler发送的消息 private Handler
handler = new Handler() { @Override public void handleMessage(Message msg) {
super.handleMessage(msg); switch (msg.what) { case PROGRESS: //1.得到当前的视频播放进程
int currentPosition = videoView.getCurrentPosition();//0
//2.SeekBar.setProgress(当前进度); seekbarVideo.setProgress(currentPosition);
//3.更新文本播放进度 tvCurrentTime.setText(utils.stringForTime(currentPosition));
//此处需要设置系统时间,下面介绍 tvSystemTime.setText(getSysteTime()); //4.每秒更新一次
handler.removeMessages(PROGRESS); handler.sendEmptyMessageDelayed(PROGRESS,
1000); break; } } };
3、播放视频进度条SeekBar拖拽事件
(1)为SeekBar设置监听 //设置视频播放SeeKbar状态变化的监听
seekbarVideo.setOnSeekBarChangeListener(new VideoOnSeekBarChangeListener());
(2)监听器实现 class VideoOnSeekBarChangeListener implements
SeekBar.OnSeekBarChangeListener { /** * 当手指滑动的时候,会引起SeekBar进度变化,会回调这个方法 *
@param seekBar * @param progress * @param fromUser 如果是用户引起的true,不是用户引起的false */
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean
fromUser) { if (fromUser) { videoview.seekTo(progress); } } /** *
当手指触碰的时候回调这个方法 * @param seekBar */ @Override public void
onStartTrackingTouch(SeekBar seekBar) { } /** * 当手指离开的时候回调这个方法 * @param seekBar
*/ @Override public void onStopTrackingTouch(SeekBar seekBar) { } }
4、音量进度条SeekBar的监听
(1)、在OnCreate()方法中,初始化AudioManager,并将SeekBar与最大音量相关联 //得到音量 am =
(AudioManager) getSystemService(AUDIO_SERVICE); currentVoice =
am.getStreamVolume(AudioManager.STREAM_MUSIC); maxVoice =
am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //最大音量和SeekBar关联
seekbarVoice.setMax(maxVoice); //设置当前进度-当前音量
seekbarVoice.setProgress(currentVoice); (2)、为音量SeekBar设置监听 //为音量SeekBar设置监听
seekbarVoice.setOnSeekBarChangeListener(new VoiceOnSeekBarChangeListener());
(3)、监听器 class VoiceOnSeekBarChangeListener implements
SeekBar.OnSeekBarChangeListener { //该参数同上述SeekBar @Override public void
onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if
(fromUser) { if (progress > 0) { isMute = false; } else { isMute = true; }
updataVoice(progress, isMute); } } @Override public void
onStartTrackingTouch(SeekBar seekBar) { } @Override public void
onStopTrackingTouch(SeekBar seekBar) { } } /** * 设置音量的大小 * @param progress */
private void updataVoice(int progress, boolean isMute) { if (isMute) {
am.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
seekbarVoice.setProgress(0); } else {
am.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
seekbarVoice.setProgress(progress); currentVoice = progress; } } (4)、将音量与实体按键相关联
/** * 监听物理健,实现声音的调节大小 * * @param keyCode * @param event * @return */ @Override
public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode ==
KeyEvent.KEYCODE_VOLUME_DOWN) { currentVoice--; updataVoice(currentVoice,
false); return true; } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
currentVoice++; updataVoice(currentVoice, false); return true; } return
super.onKeyDown(keyCode, event); }
5、效果图,见图一

三、注册监听手机电量的广播接收器和获取系统时间

1、注册监听手机电量的广播接收器
(1)在onCreate()生命周期方法内,注册监听电量的广播接收器 //此处为全局变量,因为要解除绑定 receiver = new
MyReceiver(); IntentFilter intentFiler = new IntentFilter(); //当电量变化的时候发这个广播
intentFiler.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, intentFiler); (2)、定义广播接收器 class MyReceiver extends
BroadcastReceiver { @Override public void onReceive(Context context, Intent
intent) { int level = intent.getIntExtra("level", 0);//0~100; //不同的值,设置不同的图片 if
(level <= 0) { ivBattery.setImageResource(R.drawable.ic_battery_0); } else if
(level <= 10) { ivBattery.setImageResource(R.drawable.ic_battery_10); } else if
(level <= 20) { ivBattery.setImageResource(R.drawable.ic_battery_20); } else if
(level <= 40) { ivBattery.setImageResource(R.drawable.ic_battery_40); } else if
(level <= 60) { ivBattery.setImageResource(R.drawable.ic_battery_60); } else if
(level <= 80) { ivBattery.setImageResource(R.drawable.ic_battery_80); } else if
(level <= 100) { ivBattery.setImageResource(R.drawable.ic_battery_100); } else
{ ivBattery.setImageResource(R.drawable.ic_battery_100); } } }
3、需要在onDestroy()方法内部,解除广播接收器 @Override protected void onDestroy() {
//释放资源的时候,先释放子类,在释放父类 if (receiver != null) { unregisterReceiver(receiver);
receiver = null; } super.onDestroy(); }
2、获取系统的时间
(1)、得到系统时间 public String getSysteTime() { SimpleDateFormat format = new
SimpleDateFormat("HH:mm:ss"); return format.format(new Date()); }
(2)、,在handler中,设置系统时间 //设置系统时间(上面注释掉) tvSystemTime.setText(getSysteTime());
3、见图二

四、效果

1、图一


2、图二


五、补充

1、手指上下滑动屏幕,来调节音量的高低

步骤:
(1)、获取屏幕的高和宽: screenHeight; //屏幕的高 screenWidth; //屏幕的宽 (2)、计算滑动的上下距离; //往下滑动
float distanceY = startY - endY < 0; //往上滑动 float distanceY = startY - endY >
0; (3)、利用公式,计算改变的声音; //公式:滑动屏幕的距离: 总距离 = 改变声音:音量最大值 改变声音 = (滑动屏幕的距离 :总距离)*
音量最大值 (4)、得到最终声音; 最终声音 = 原来的声音 + 改变声音;
2、在事件中,得到需要的变量值
(1)、onTouchEvent事件方法里,在按下(down)的时候得到: startY //开始位置 totalDis //屏幕的总距离 cVol
//当前音量 (2)、onTouchEvent事件方法里,在移动(move)的时候得到: float endY = envent.getY();
//得到结束位置 float distanceY = endY - startY; //得到计算距离 改变声音 = (滑动屏幕的距离 :总距离)* 音量最大值
//得到改变的音量 最终声音 = cVol + 改变声音; updataVoice(); //设置音量
3、具体代码
//得到屏幕的宽和高方式 DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); screenWidth
= displayMetrics.widthPixels; screenHeight = displayMetrics.heightPixels;
private float startY; private float totalDis; //屏幕的高(总距离) private int cVol;
//一触碰屏幕时的当前音量 @Override public boolean onTouchEvent(MotionEvent event) { switch
(event.getAction()) { case MotionEvent.ACTION_DOWN://手指按下 //1.按下记录值 startY =
event.getY(); cVol = am.getStreamVolume(AudioManager.STREAM_MUSIC); totalDis=
Math.min(screenHeight, screenWidth); break; case MotionEvent.ACTION_MOVE://手指移动
float endY = event.getY(); float distanceY = startY - endY; //改变声音 = (滑动屏幕的距离:
总距离)*音量最大值 float delta = (distanceY / totalDis) * maxVoice; //最终声音 = 原来的 +
改变声音; int voice = (int) Math.min(Math.max(cVol + delta, 0), maxVoice); if
(delta != 0) { isMute = false; updataVoice(voice, isMute); } break; case
MotionEvent.ACTION_UP://手指离开 break; } return super.onTouchEvent(event); }

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信