您的位置:首页 > 移动开发 > Android开发

Android 音乐播放器的开发教程(八)歌曲的切换和进度条的拖动 ----- 小达

2015-01-01 10:44 489 查看

歌曲的切换和进度条的拖动

大家新年快乐~~~~~~

,2015年的第一天哦,前两天偷了点懒,木有继续完成我的博客,话说这博客写的时间也真够长的啊,写了一年了都还没有弄完,

,今天我就是来兑现上一次的承诺,将进度条的拖动和切歌的功能加入到播放器中.

首先是进度条的拖动,其实现的原理就是拖动进度条松手之后,将当前进度条处于的位置用Broadcast的方式发送给service,让service从当前位置开始播放.在网上找了哈,按钮有onClickListener,那么我们自然可以联想到,进度条是否有个类似的东西呢?果然就有个东西叫OnSeekBarChangeListener,需要重写其中的三个方法,onProgressChanged,onStartTrackingTouch,onStopTrackingTouch,小达在这里实现的是最后一个方法,前面两个都没管,从命名来看,三个函数的意思很容易理解了,第一个是进度条的值每变动一哈,就要调用(有没有感觉进度条这个样子好累好累的,,,100块都不给别人),第二个就是刚开始改变就调用,我们需要的是在放手的那一刻,进度条的数值,所以第三个还是很不错的..

实现的代码如下所示,在MainActivity给进度条加上把:
private Intent progress_change_intent_to_service;    //先来一个发送广播的Intent
progress_change_intent_to_service = new Intent("com.example.communication.PROGRESS_BAR");
</pre><pre name="code" class="java">
seek_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {                             //进度条拖动响应
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {}

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                current_position_bar = seekBar.getProgress();
                progress_change_intent_to_service.putExtra("current_position",current_position_bar);
                sendBroadcast(progress_change_intent_to_service);
            }
        });


再切换到PlayerService.java中,创建广播的***:
private ProgressChangeReceiver progressChangeReceiver;

        progressChangeReceiver = new ProgressChangeReceiver();

    private class ProgressChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            current_position = intent.getIntExtra("current_position", 0);
            playMusic(current_position);
        }
    }

        IntentFilter intentProgressChangeFilter = new IntentFilter();

        intentProgressChangeFilter.addAction("com.example.communication.PROGRESS_BAR");

        registerReceiver(progressChangeReceiver, intentProgressChangeFilter);


到这里,进度条就可以随心而动了,怎么是不是很爽滑~~~~.

下面就该切歌咯,上一首和下一首,先给activity里的两个按钮加上两个监听器:
next_song_button.setOnClickListener(new View.OnClickListener() {             //下一首按钮的监听器
            @Override
            public void onClick(View v) {

                changeMusic(play_mode,AppConstant.PlayerMsg.NEXT_MUSIC,mp3Infos);

            }
        });

        previous_song_button.setOnClickListener(new View.OnClickListener() {        //上一首按钮监听
            @Override
            public void onClick(View v) {
                changeMusic(play_mode,AppConstant.PlayerMsg.PREVIOUS_MUSIC,mp3Infos);
            }
        });


注意里面的参数有一个play_mode,播放模式,这里只有两种播放模式,其他的可以自己再去做做,在activity中弄一个变量专门来记录当前的播放模式,在开始的时候我们已经把播放模式的常量加入了一个类中,现在再看一下,:
package com.example.dada.myapplication;

public interface AppConstant {
    public class PlayerMsg{
        public static final int PLAY_MSG = 1;                      //开始播放
        public static final int PAUSE = 2;                         //暂停播放
        public static final int PREVIOUS_MUSIC = 3;                //上一首
        public static final int NEXT_MUSIC = 4;                    //下一首
        public static final int LOOP_MODE = 5;                     //循环播放
        public static final int RANDOM_MODE = 6;                   //随机播放
        public static final int CHANGE_TO_MY_MUSIC_FRAGMENT=7;     //更换fragment消息
        public static final int LIST_CLICK = 8;                    //列表点击
        public static final int BACK_TO_MAIN_FRAGMENT=9;           //回退到主fragment
        public static final int DISMISS_CLICK = 10;                //回退到主fragment
        public static final int FRAGMENT_RANDOM_PLAY = 11;         //小卷毛点歌
        public static final int ADD_TO_F***ORITE = 12;              //加入我的最爱
        public static final int DELETE_FROM_F***ORITE = 13;         //删除我的最爱
    }

    public class NotificationMsg{
        public static final String NOTIFICATION_PREVIOUS_MUSIC = "PREVIOUS";
        public static final String NOTIFICATION_NEXT_MUSIC = "NEXT";
        public static final String NOTIFICATION_PAUSE_MUSIC = "PLAY";
        public static final String NOTIFICATION_EXIT = "EXIT";
    }
}


其中有随机播放和循环播放两种模式的,在MainActivity中的play_mode变量就只有这两个值,用这种方式来控制歌曲的切换模式.
给播放模式的按钮添加监听器,点击之后会弹出一个popupwindow,也就是弹出式的窗口,用来给用户选择播放模式.

play_mode_button = (ImageButton)findViewById(R.id.play_mode_button);
        play_mode_button.setImageResource(R.drawable.play_mode_photo);

play_mode_button.setOnClickListener(new View.OnClickListener() {                                        //播放模式按钮监听器
            @Override
            public void onClick(View v) {
</pre><pre name="code" class="java">/*如果弹出式窗口显示了,点击之后就关闭弹出式窗口,如果没有显示,就显示窗口
*/
                if(popupPlayModeWindow.isShowing()){
                    popupPlayModeWindow.dismiss();
                }
                else{
</pre><pre name="code" class="java">/*直接改变记录播放模式的变量值
*/
                    if(play_mode == AppConstant.PlayerMsg.LOOP_MODE)
                        Toast.makeText(getApplicationContext(), "当前模式为循环播放模式", Toast.LENGTH_SHORT).show();
                    if(play_mode == AppConstant.PlayerMsg.RANDOM_MODE)
                        Toast.makeText(getApplicationContext(),"当前模式为随机播放模式",Toast.LENGTH_SHORT).show();
                    popupPlayModeWindow.showAsDropDown(v);
                }
            }
        });


下面就是关于弹出式窗口的介绍了,一般的弹出式有两种,一种是用activity设置其形式为弹出式的,还有一种是popupwindow,这里用到了popupwindow,
private PopupWindow popupPlayModeWindow;                               //播放模式下拉窗口

        View play_mode_window = this.getLayoutInflater().inflate(R.layout.popup_window_layout,null);
        popupPlayModeWindow = new PopupWindow(play_mode_window,280,360);
其中需要用到一个布局文件popup_window_layout,,,,用来规划弹出式窗口的布局的,,还有里面的280和360可以自己调节大小的.布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/music_down_menu_bg">

    <Button
        android:id="@+id/loop_play_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="10pt"
        android:background="#00000000"
        android:text="循 环 播 放"
        android:onClick="loop_play_mode_listener"/>

    <Button
        android:id="@+id/random_play_mode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="10pt"
        android:background="#00000000"
        android:text="随 机 播 放"
        android:onClick="random_play_mode_listener"/>

</LinearLayout>


其中有两个按钮,,在MainActivity中加入两个按钮的监听器,
public void loop_play_mode_listener(View v){
        Toast.makeText(getApplicationContext(),"更改为循环播放模式",Toast.LENGTH_SHORT).show();
        play_mode = AppConstant.PlayerMsg.LOOP_MODE;
        play_mode_button.setImageResource(R.drawable.play_mode_photo);
        popupPlayModeWindow.dismiss();
    }

    public void random_play_mode_listener(View v){
        Toast.makeText(getApplicationContext(),"更改为随机播放模式",Toast.LENGTH_SHORT).show();
        play_mode = AppConstant.PlayerMsg.RANDOM_MODE;
        play_mode_button.setImageResource(R.drawable.random_play_mode);
        popupPlayModeWindow.dismiss();
    }


现在就可以自由的改变播放模式了,点击了按钮之后会有几个Toast来提示用户信息.Toast即经常在屏幕下方弹出的小提示框,估计是像土司烤好了弹出来一样吧

.现在还差一样,就是切歌的主要实现函数.

下面是changeMusic()的代码

private void changeMusic(int mode,int msg,List<Mp3Info> mp3Infos){
        isChangToNext = true;
        isPause = false;
        current_position = 0;
        play_button.setImageResource(R.drawable.pause_photo);                 
        switch (mode){                                                                             //对当前的播放模式作出判断,进行不同的处理
            case AppConstant.PlayerMsg.LOOP_MODE:
                switch (msg){
                    case AppConstant.PlayerMsg.NEXT_MUSIC:                  //循环模式就按照是上一曲还是下一曲,切换当前播放音乐在音乐列表中的位置
//而随机模式大家都懂的,随便在列表中取出一个位置的歌曲来播放,注意不要出界就好啦
                        if(music_position < mp3Infos.size() - 1 )
                            music_position ++;
                        else
                            music_position = 0;

                        break;

                    case AppConstant.PlayerMsg.PREVIOUS_MUSIC:
                        if(music_position >=  1 )
                            music_position --;
                        else
                            music_position = mp3Infos.size() - 1;
                        break;
                }
                break;

            case AppConstant.PlayerMsg.RANDOM_MODE:
                music_position = (int)(Math.random() * (mp3Infos.size() - 1));
                break;
        }

        try{
            initService(music_position);                                                               //重新初始化一个service,将切换到的歌曲信息传给service
            Mp3Info mp3_Info = mp3Infos.get(music_position);
            isFavorite = mp3_Info.getFavorite();

            music_url = mp3_Info.getUrl();

            music_info_textView.setText(mp3_Info.getTitle());
            singer_info_textView.setText(mp3_Info.getArtist());
            seek_bar.setMax((int)mp3_Info.getDuration());
            intent_to_service.putExtra("isPause",isPause);

            intent_to_changeMusic.putExtra("music_title",mp3_Info.getTitle());
            intent_to_changeMusic.putExtra("music_artist",mp3_Info.getArtist());

            intent_to_changeMusic.putExtra("music_url",music_url);
            intent_to_changeMusic.putExtra("isChangeToNext",isChangToNext);
            sendBroadcast(intent_to_service);
            sendBroadcast(intent_to_changeMusic);

            isChangToNext = false;

        }
        catch(Exception e){
            e.printStackTrace();
        }

    }


在这个函数中向service发送了切换歌曲的广播,故在activity和service中需要做一些关于广播的工作,在前面的博客中有详细的介绍,这里直接给出源代码了哈,
这里是在activity为发送广播做准备,
private Intent intent_to_changeMusic;

  intent_to_changeMusic = new Intent("com.example.communication.ChANGE_MUSIC");


在service的onStartCommand函数中添加IntentFilter
IntentFilter intentChangeFilter = new IntentFilter();

        intentChangeFilter.addAction("com.example.communication.ChANGE_MUSIC");
//字符串注意和activity中的一致.

        registerReceiver(changeToNextReceiver, intentChangeFilter);


再加入一个changeToNextReceiver,就可以对接收到广播之后做出处理,整个切歌的功能也就实现拉~~~~~233333
private ChangeToNextReceiver changeToNextReceiver;

        changeToNextReceiver = new ChangeToNextReceiver();

    private class ChangeToNextReceiver extends BroadcastReceiver {                        //换歌广播***

        public ChangeToNextReceiver() {
            super();
        }

        @Override
        public void onReceive(Context context, Intent intent) {

            isChangToNext = intent.getBooleanExtra("isChangeToNext", false);

            if (isChangToNext) {
                musicPath = intent.getStringExtra("music_url");
                music_artist = intent.getStringExtra("music_artist");
                music_title = intent.getStringExtra("music_title");
                playMusic(0);
            }
        }
    }


到现在,播放器就可以无压力的到处切歌~~~~~进度条爽滑的拖动了,如果还有什么疑问的话,记得给我留言哦,或者联系我的QQ ,基本都是除了睡觉都在线的,小达有什么做的不对和不妥的地方,望各位也能给我指出,让我快快的进步

,好啦,这篇博客就写到这里咯,下篇中我们将介绍,关于歌词的提取与显示(这个可能在有些设备上行不通,不知道为什么,我也理解的不是特别的深刻,就当是复习一下把,嘿嘿),下篇博客我们再见咯~~~88,还有,祝大家新年快乐,万事如意哈~~~,还有调程序一调就通,程序无bug,无error,无warning~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐