当前位置:   article > 正文

Android-MediaPlayer(2)加进度条和时间显示_android seekbar加上时间点

android seekbar加上时间点

SeekBar使用显示歌曲播放进度及时间

上一篇:Android MediaPlayer
我们之前播放音乐的时候都会有进度条,今天我们就来加一个进度条,并显示你的播放进度和当前歌曲时间。
我们先看看效果吧万一不是你要的那个,不就浪费你的时间了,效果图如下:
在这里插入图片描述
在这里插入图片描述
(不可否认,丑是丑了点,但是有内涵,你懂得啊!)
接下来就来实现这个效果吧。
我们就不新建项目了,就用之前的那个MediaPlayerDemo吧,如果你是第一次看,可以点击最上方的链接去看前一篇文章。
1.修改activity_layout.xml
我们既然要加进度条和时间显示肯定是要先修改布局文件的,修改代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_weight="1">

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_marginLeft="10dp"
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:id="@+id/tv_start" />

        <SeekBar
            android:layout_width="270dp"
            android:layout_height="wrap_content"
            android:id="@+id/seekbar" />

        <TextView
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:id="@+id/tv_end" />
    </LinearLayout>

    <LinearLayout
        android:gravity="bottom"
        android:layout_marginBottom="2dp"
        android:layout_gravity="bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/play"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Play"/>
        <Button
            android:id="@+id/pause"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Pause"/>
        <Button
            android:id="@+id/stop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Stop"/>
    </LinearLayout>
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

可以看到我们新增了两个LinearLayout(线性布局),一个留着备用,第二个里面我们放了两个TextView(用于显示时间)和一个SeekBar(进度条)。
我们想一下,我们已经知道这个音频文件放在手机里面了,也已经可以播放了,那么我要用进度条来显示当前歌曲的播放进度该怎么做,并且你可以通过手指拖拽这个Seekbar来到你想要的歌曲片段出,并且松手就要播放音乐·,还有就是怎么获取这个歌曲的时间呢?带着问题去想怎么实现会让你有种恍然大明白的感觉(你也别嫌我啰嗦啊,正所谓同是天涯程序员,相煎何太急啊!)。

首先是SeekBar的使用

		protected SeekBar seekBar;//进度条
		private Timer timer;//定时器
		protected TextView tv_start;//开始时间
		protected TextView tv_end;//结束时间
		private boolean isSeekbarChaning;//互斥变量,防止进度条和定时器冲突。
		private Button play;//播放按钮
		private Button pause;//暂停按钮
		private Button stop;//停止按钮
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
		//绑定监听器,监听拖动到指定位置
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int duration2 = mediaPlayer.getDuration() / 1000;//获取音乐总时长
                int position = mediaPlayer.getCurrentPosition();//获取当前播放的位置
                tv_start.setText(calculateTime(position / 1000));//开始时间
                tv_end.setText(calculateTime(duration2));//总时长
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                isSeekbarChaning = true;
            }  
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                isSeekbarChaning = false;
                mediaPlayer.seekTo(seekBar.getProgress());//在当前位置播放
                tv_start.setText(calculateTime(mediaPlayer.getCurrentPosition() / 1000));
            }
        });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

解释一下,首先我们定义了SeekBar,然后调用SeekBar的setOnSeekBarChangeListener()(PS:这个方法的意思是进图条改变时执行,无论是自己改变还是人为改变都会执行)方法。然后它里面会有是三个构造方法,分别是onProgressChanged()onStartTrackingTouch()onStopTrackingTouch()。刚看到这个你可能有点懵,解释一下,
**1.onProgressChanged()**这个方法我理解为进度条改变时使用的方法。这里面有三个参数,seekbar就是进度条,progress就是进度值,而fromUser参数,这个参数的作用是触发SeekBar的onProgressChanged回调接口时,可以根据这个参数判断是手动滑动SeekBar还是其他的一些方式改变了SeekBar的值。
2.onStartTrackingTouch通知用户已经开始一个触摸拖动手势。
**3.onStopTrackingTouch()**通知用户触摸手势已经结束。
现在应该好理解了吧。
还有就是计算播放时间的,代码如下:

	//计算播放时间
    public String calculateTime(int time) {
        int minute;
        int second;
        if (time >= 60) {
            minute = time / 60;
            second = time % 60;
            //分钟在0~9
            if (minute < 10) {
                //判断秒
                if (second < 10) {
                    return "0" + minute + ":" + "0" + second;
                } else {
                    return "0" + minute + ":" + second;
                }
            } else {
                //分钟大于10再判断秒
                if (second < 10) {
                    return minute + ":" + "0" + second;
                } else {
                    return minute + ":" + second;
                }
            }
        } else {
            second = time;
            if (second >= 0 && second < 10) {
                return "00:" + "0" + second;
            } else {
                return "00:" + second;
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

算法到是不难,需要理解一下,先定义分钟和秒,然后给一个时间判断,大于60的话就得出下面的分钟和秒,如果在0至9分钟之内,则判断具体多少秒。如果分钟大于10再判断秒。相信你看得懂。
然后我们看一下**initMediaPlayer()**里面要怎么添加这个时间,代码如下:

	/*
    * 初始化MediaPlayer
    * */
    private void initMediaPlayer(){
        try {
            File file = new File(Environment.getExternalStorageDirectory(),"music.mp3");
            mediaPlayer.setDataSource(file.getPath());//指定音频文件的路径
            mediaPlayer.prepare();//让MediaPlayer进入到准备状态
        }catch (Exception e){
            e.printStackTrace();
        }
        int duration2 = mediaPlayer.getDuration() / 1000;
        int position = mediaPlayer.getCurrentPosition();
        tv_start.setText(calculateTime(position / 1000));
        tv_end.setText(calculateTime(duration2));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

通过定义一个两个值,一个播放时间,一个播放位置,开始时间通过刚才的算法得出赋值给tv_start显示在界面上。结束时间,通过计算赋值给定义的值,在赋值给tv_end显示在界面上。然后来看看**initView()**方法,我们的SeekBar的监听事件就是放在这个下面的,这个方法的完整代码如下:

	/*
    * 初始化
    * */
    private void initView(){
        tv_start = (TextView)findViewById(R.id.tv_start);
        tv_end = (TextView)findViewById(R.id.tv_end);
        seekBar = (SeekBar)findViewById(R.id.seekbar);
        //绑定监听器,监听拖动到指定位置
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int duration2 = mediaPlayer.getDuration() / 1000;//获取音乐总时长
                int position = mediaPlayer.getCurrentPosition();//获取当前播放的位置
                tv_start.setText(calculateTime(position / 1000));//开始时间
                tv_end.setText(calculateTime(duration2));//总时长
            }
            /*
            * 通知用户已经开始一个触摸拖动手势。
            * */
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                isSeekbarChaning = true;
            }
            /*
            * 当手停止拖动进度条时执行该方法
            * 首先获取拖拽进度
            * 将进度对应设置给MediaPlayer
            * */
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                isSeekbarChaning = false;
                mediaPlayer.seekTo(seekBar.getProgress());//在当前位置播放
                tv_start.setText(calculateTime(mediaPlayer.getCurrentPosition() / 1000));
            }
        });

        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        stop.setOnClickListener(this);

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

相信你都理解为什么这么做,最上面的就是我们开始时间、结束时间和进度条。最下面就是三个按钮的点击监听事件,为什么可以这样写,请看上一篇文章,我修改了一下onClick(),方法代码如下:

	@Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.play:
                if(!mediaPlayer.isPlaying()){
                    mediaPlayer.start();//开始播放
                    int duration = mediaPlayer.getDuration();//获取音乐总时间
                    seekBar.setMax(duration);//将音乐总时间设置为Seekbar的最大值
                    timer = new Timer();//时间监听器
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            if(!isSeekbarChaning){
                                seekBar.setProgress(mediaPlayer.getCurrentPosition());
                            }
                        }
                    },0,50);
                }
                break;
            case R.id.pause:
                if(mediaPlayer.isPlaying()){
                    mediaPlayer.pause();//暂停播放
                }
                break;
            case R.id.stop:
                if(mediaPlayer.isPlaying()){
                    mediaPlayer.reset();//停止播放
                    initMediaPlayer();
                }
                break;
            default:
                break;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

主要的改动还是在启动播放里面主要是时间监听器,isSeekbarChaning为True时改变进度条。因为之前我们给它赋值为False,所以!isSeekbarChaning就为True。大致就是这样了,最后面,我放上MainActivity的所有代码,不然可能会被骂啊。

MainActivity.java完整代码如下:

package com.example.mediaplayerdemo;

import android.Manifest;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

//继承View.OnClickListener,是按钮放在一起更直观,用另一种方法来设置按钮点击监听
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    //定义三个按钮并实例化MediaPlayer
    private MediaPlayer mediaPlayer = new MediaPlayer();

    protected TextView tv_start;
    protected TextView tv_end;
    protected SeekBar seekBar;
    private Timer timer;//定时器
    private boolean isSeekbarChaning;//互斥变量,防止进度条和定时器冲突。
    private Button play;
    private Button pause;
    private Button stop;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        play = (Button)findViewById(R.id.play);
        pause = (Button)findViewById(R.id.pause);
        stop = (Button)findViewById(R.id.stop);
        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        stop.setOnClickListener(this);
        if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(MainActivity.this,new String[]{
                    Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        }else {
            initView();//初始化进度条
            initMediaPlayer();//初始化MediaPlayer
        }
    }

    /*
    * 初始化
    * */
    private void initView(){
        tv_start = (TextView)findViewById(R.id.tv_start);
        tv_end = (TextView)findViewById(R.id.tv_end);
        seekBar = (SeekBar)findViewById(R.id.seekbar);
        //绑定监听器,监听拖动到指定位置
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int duration2 = mediaPlayer.getDuration() / 1000;//获取音乐总时长
                int position = mediaPlayer.getCurrentPosition();//获取当前播放的位置
                tv_start.setText(calculateTime(position / 1000));//开始时间
                tv_end.setText(calculateTime(duration2));//总时长
            }
            /*
            * 通知用户已经开始一个触摸拖动手势。
            * */
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                isSeekbarChaning = true;
            }
            /*
            * 当手停止拖动进度条时执行该方法
            * 首先获取拖拽进度
            * 将进度对应设置给MediaPlayer
            * */
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                isSeekbarChaning = false;
                mediaPlayer.seekTo(seekBar.getProgress());//在当前位置播放
                tv_start.setText(calculateTime(mediaPlayer.getCurrentPosition() / 1000));
            }
        });

        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        stop.setOnClickListener(this);

    }

    //计算播放时间
    public String calculateTime(int time) {
        int minute;
        int second;
        if (time >= 60) {
            minute = time / 60;
            second = time % 60;
            //分钟在0~9
            if (minute < 10) {
                //判断秒
                if (second < 10) {
                    return "0" + minute + ":" + "0" + second;
                } else {
                    return "0" + minute + ":" + second;
                }
            } else {
                //分钟大于10再判断秒
                if (second < 10) {
                    return minute + ":" + "0" + second;
                } else {
                    return minute + ":" + second;
                }
            }
        } else {
            second = time;
            if (second >= 0 && second < 10) {
                return "00:" + "0" + second;
            } else {
                return "00:" + second;
            }
        }
    }
    /*
    * 初始化MediaPlayer
    * */
    private void initMediaPlayer(){
        try {
            File file = new File(Environment.getExternalStorageDirectory(),"music.mp3");
            mediaPlayer.setDataSource(file.getPath());//指定音频文件的路径
            mediaPlayer.prepare();//让MediaPlayer进入到准备状态
        }catch (Exception e){
            e.printStackTrace();
        }
        int duration2 = mediaPlayer.getDuration() / 1000;
        int position = mediaPlayer.getCurrentPosition();
        tv_start.setText(calculateTime(position / 1000));
        tv_end.setText(calculateTime(duration2));
    }
    //使用时弹出提示框
    public void onRequestPermissionResult(int requestCode,String[] permissions,int[] grantResults){
         switch (requestCode){
             case 1:
                 if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                     initView();
                     initMediaPlayer();

                 }else {
                     Toast.makeText(this,"拒绝权限将无法使用程序",Toast.LENGTH_SHORT).show();
                     finish();
                 }
                 break;
             default:
         }
    }

    @Override
    public void onClick(View v){
        switch (v.getId()){
            case R.id.play:
                if(!mediaPlayer.isPlaying()){
                    mediaPlayer.start();//开始播放
                    int duration = mediaPlayer.getDuration();//获取音乐总时间
                    seekBar.setMax(duration);//将音乐总时间设置为Seekbar的最大值
                    timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            if(!isSeekbarChaning){
                                seekBar.setProgress(mediaPlayer.getCurrentPosition());
                            }
                        }
                    },0,50);
                }
                break;
            case R.id.pause:
                if(mediaPlayer.isPlaying()){
                    mediaPlayer.pause();//暂停播放
                }
                break;
            case R.id.stop:
                if(mediaPlayer.isPlaying()){
                    mediaPlayer.reset();//停止播放
                    initMediaPlayer();
                }
                break;
            default:
                break;
        }
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        if(mediaPlayer != null){
            mediaPlayer.stop();
            mediaPlayer.release();

        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208

感觉这个不完善吗?没有关系,可以看下面这篇文章,可以扫描手机的本地音乐,添加到列表上,并且播放出来,比现在看起来要更高大上呢

Android 本地音乐播放器含扫描本地音乐,音乐切换,状态监听

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/789184
推荐阅读