2016-06-27 51 views
3

我正在从this tutorial实施音乐应用程序。如何处理MediaPlayer和BaseAdapter

有一个BaseAdapter类用来显示曲目列表和一个MusicPlayer类来播放音乐。这两者都是我主要活动类的变量。

public class MainActivity extends Activity implements MediaPlayerControl{ 
     private MediaPlayer musicSrv; 
     private BaseAdapter songAdt; 
     ... 

当前完成时,MusicPlayer播放下一首曲目。向BaseAdapter发送消息以更改每个新播放轨道的显示(如更改当前轨道的颜色)的最佳方式是什么?

编辑

根据该意见,似乎使用界面良好的是一个不错的选择。有人可以写一个详细的答案,解释如何做到这一点?谢谢。

回答

1

多亏了意见,我成功地实现了接口的解决方案。

这是我的主要活动类,即刷新BaseAdapater每个歌曲改变时:

public class MainActivity extends Activity implements MusicService.SongChangedListener { 
     private MediaPlayer musicSrv; 
     private BaseAdapter songAdt; 
     ... 

     @Override 
     public void songChanged(Song currentSong){ 
      songAdt.notifyDataSetChanged(); // refresh view 
     } 

而且我MusicService类:

public class MusicService extends Service implements MediaPlayer.OnPreparedListener{ 
... 
private MainActivity activity; 
... 

public void setActivity(MainActivity act){ 
    //set the activity 
    activity = act; 
} 

public interface SongChangedListener { 
    void songChanged(Song song); 
} 
... 
public void playSong(){ 
     // this function is called each time a new song is played 
     activity.songChanged(playSong); 
     ... 
} 
0

BaseAdapter的方法getView()方法将为您提供视图,您应该通过在列表中设置变量并在未设置变量时将该颜色重置为默认值来更改当前轨道的颜色。

if (is this the current playing track) { 
    // Set the color of the view. 
} else { 
    // Set the color to default. 
} 

如果您目前实施这种逻辑,那么只要更改当前曲目,并在你的列表中跟踪当前正在播放的媒体)变量,一个简单的songAdt.notifyDataSetChanged(将要求BaseAdapter来再次调用,并根据新数据设置视图。为了更深入地理解ListView,你可以参考this talk。我会帮你的。

最好考虑用RecyclerView,它的礼物来训练自己。 ListView是一个可怕的过去。

public class Activity implements SongChangedListener { 
... 
    @Override 
    onCreate() { 
     .... 
     PlayerManager pManager = new PlayerManager(); 
    } 

    onResume() { 
     pManager.setListener(this); 
    } 

    onPause() { 
     pManager.setListener(null); 
    } 

    @Override 
    void songChanged (MediaId idOfSong) { 
     if (getActivity == null) //If you received a callback after activity was killed. 
      return; 
     // Change the current song as not playing in List. (for your adapter) 
     // Change the idOfSong to currently playing in List (for your adapter). 
     // change currentSong = idOfSong; 
     // notify that the data in List has changed (songAdt.notifyDataSetChanged) 
    } 

} 

,并在您PlayerManager,您可以创建界面,或者也许是因为接口一个单独的类,不要紧,你如何发送接口实例。

public class PlayerManager { 
    ... 
    private SongChangedListener mListener; 
    ... 

    public PlayerManager() { 
    } 

    public void setListener(SongChangedListener listener) { 
     mListener = listener; 
    } 

    public interface SongChangedListener { 
     void songChanged(MediaId idOfSong); 
    } 

    ... 
    public void playSong() { 
     ... 
     if (mListener != null) 
      mListener.songChanged(idOfNextSong); 
     ... 
    } 

在你的答案要传递活动进入你的服务,感觉错在许多方面。如果你想实现活动和服务之间的沟通,还有很多其他方法可以做到这一点。通常我使用一个Messenger和一个Handler。我会提供更多详细信息,但如果您在文档和其他答案中进行探索,它会更有用。一旦你了解信使如何工作,很容易实现。另外,如果你正在寻找一个完整的MediaPlayer应用程序,你的实现将需要更多的锅炉代码。您还必须处理MediaButton点击(如果有人点击蓝牙耳机或手表上的播放/暂停)。 MediaSessionCompat最好是更好的实现。您也可以参考以下开源的MediaPlayer,它非常好地实现了所有最低要求的功能android-UniversalMusicPlayer

+0

我有一个songAdt.notifyDataSetChanged()在我的主要活动课上。我手动更改歌曲时使用它。 MediaPlayer在完成后自动切换到下一首歌曲时出现问题。由于songAdt未知,因此无法在MediaPlayer类中调用songAdt.notifyDataSetChanged()。 – PatriceG

+1

尝试添加回调,在你的媒体播放器类中创建一个接口,并有一个名为songChanged()的方法。在你的mainActivity中实现这个接口,当你在MediaPlayer类中改变歌曲时调用这个方法,这样歌曲的改变就会反映在你的mainActivity中。这是一个非常常见的设计,通过回调来通知活动的变化。 – Roadblock

+1

U将不得不将一个你的mainActivity的实例传递给MediaPlayer类(使用MediaPlayers构造函数)。使用此实例调用songChanged方法。 – Roadblock

0

在您的音乐曲目模型类中维护一个变量,指示此歌曲是否处于播放模式。

检查getView()中的值并根据它进行编码。

if(model.is_playing) 
    //change your code for playing song 
else 
    //rest songs which are not playing 

现在,只要你manualy或automaticaly变化的歌曲,改变is_playing值,取消它从一首曲目,并设置为当前播放的曲目。

+0

是的,但必须刷新BaseAdapter,不是吗?怎么做? – PatriceG

+0

更新列表后,您可以使用'notifyDatasetChanged()' –

+0

我的问题是BaseAdapter在MusicPlayer类中不知道,其中的歌曲更改。 – PatriceG

0

你不需要实现你自己的回调接口。当播放声音结束时,Mediaplayer已经有一个oncompletionlistener。所以,你只需要刷新您的适配器在oncompletion方法

public class MainActivity extends Activity implements MediaPlayerControl, MediaPlayer.OnCompletionListener{ 
    private MediaPlayer musicSrv; 
    private BaseAdapter songAdt; 


    @Override 
    public void onCreate() { 
     musicSrv.setOnCompletionListener(this); 
    } 

    @Override 
    public void onCompletion(MediaPlayer musicPlayer) { 
     songAdt.notifyDataSetChanged(); 
    } 
} 
+0

请添加一些解释你的帖子,你试图展示和为什么等。 – Mfusiki

+0

我已经添加了一个解释。 –