如何处理 MediaPlayer 和 BaseAdapter
How to deal with MediaPlayer and BaseAdapter
我正在实施来自 this tutorial 的音乐应用程序。
有一个BaseAdapterclass用来显示曲目列表,还有一个MusicPlayerclass用来播放音乐。两者都是我的主要变量 activity class.
public class MainActivity extends Activity implements MediaPlayerControl{
private MediaPlayer musicSrv;
private BaseAdapter songAdt;
...
MusicPlayer 在当前曲目结束时播放下一首曲目。向 BaseAdapter 发送消息以更改每个新播放曲目的显示(例如更改当前曲目的颜色)的最佳方法是什么?
编辑
根据评论,使用一个接口good似乎是个不错的选择。有人可以写一个详细的答案来解释如何做吗?谢谢
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 中,您可以创建接口,或者为接口创建一个单独的 class,无论您如何发送接口实例。
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);
...
}
在您的回答中,您将 activity 传递到您的服务中,这在很多方面都让人感觉不对。如果你想实现 activity 和服务之间的通信,还有很多其他的方法可以做到这一点。通常我将 Messenger 与 Handler 结合使用。我会提供更多细节,但如果您在文档和其他答案中探索它会更有益。一旦您了解了 Messengers 的工作原理,就很容易实施。
此外,如果您正在寻找功能完备的 MediaPlayer 应用程序,您的实现将需要更多的锅炉代码。此外,您还必须处理 MediaButton 的点击(如果有人在他们的蓝牙耳机或手表上点击 play/pause)。最好是MediaSessionCompat is a better implementation. You can also refer the following open Source MediaPlayer, which implements all the minimum required functionalities pretty nicely android-UniversalMusicPlayer.
在您的音乐曲目模型中维护一个变量class,它指示这首歌曲是否处于播放模式。
检查您 getView()
中的值并根据它进行编码。
if(model.is_playing)
//change your code for playing song
else
//rest songs which are not playing
现在,无论您是手动还是自动更改歌曲,都请更改 is_playing
值,将其从之前的曲目中取消设置并将其设置为当前播放的曲目。
您不需要实现自己的回调接口。当播放声音终止时,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();
}
}
感谢评论,我设法实现了一个带有接口的解决方案。
这是我的 Main activity class,每次更改歌曲时都会刷新 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 class:
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);
...
}
我正在实施来自 this tutorial 的音乐应用程序。
有一个BaseAdapterclass用来显示曲目列表,还有一个MusicPlayerclass用来播放音乐。两者都是我的主要变量 activity class.
public class MainActivity extends Activity implements MediaPlayerControl{
private MediaPlayer musicSrv;
private BaseAdapter songAdt;
...
MusicPlayer 在当前曲目结束时播放下一首曲目。向 BaseAdapter 发送消息以更改每个新播放曲目的显示(例如更改当前曲目的颜色)的最佳方法是什么?
编辑
根据评论,使用一个接口good似乎是个不错的选择。有人可以写一个详细的答案来解释如何做吗?谢谢
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 中,您可以创建接口,或者为接口创建一个单独的 class,无论您如何发送接口实例。
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);
...
}
在您的回答中,您将 activity 传递到您的服务中,这在很多方面都让人感觉不对。如果你想实现 activity 和服务之间的通信,还有很多其他的方法可以做到这一点。通常我将 Messenger 与 Handler 结合使用。我会提供更多细节,但如果您在文档和其他答案中探索它会更有益。一旦您了解了 Messengers 的工作原理,就很容易实施。
此外,如果您正在寻找功能完备的 MediaPlayer 应用程序,您的实现将需要更多的锅炉代码。此外,您还必须处理 MediaButton 的点击(如果有人在他们的蓝牙耳机或手表上点击 play/pause)。最好是MediaSessionCompat is a better implementation. You can also refer the following open Source MediaPlayer, which implements all the minimum required functionalities pretty nicely android-UniversalMusicPlayer.
在您的音乐曲目模型中维护一个变量class,它指示这首歌曲是否处于播放模式。
检查您 getView()
中的值并根据它进行编码。
if(model.is_playing)
//change your code for playing song
else
//rest songs which are not playing
现在,无论您是手动还是自动更改歌曲,都请更改 is_playing
值,将其从之前的曲目中取消设置并将其设置为当前播放的曲目。
您不需要实现自己的回调接口。当播放声音终止时,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();
}
}
感谢评论,我设法实现了一个带有接口的解决方案。
这是我的 Main activity class,每次更改歌曲时都会刷新 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 class:
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);
...
}