一、引言
在上文中,我们通过自定义控制面板的布局,来实现自定义的播放控制,下面来对里面的各个组件进行事件绑定。
@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);
}