我正在尝试使用音频消息实现RecyclerView
并播放这些音频文件。以前我在ImageButton
,so I found this solution and changed my code accordingly.改变播放和暂停图像时遇到了问题但现在我面临另一个问题。每当我播放音频时,图像会变为暂停,当我再次单击此按钮时,它会给我一个错误:pause called in state 8
。我知道是什么导致了这个问题,但无法弄清楚解决方案。
这是我的onBindViewHolder:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((MyChatMediaViewHolder) holder).bindData(mChats.get(position), position);
}
这是我的MyChatMediaViewHolder
课程:
private class MyChatMediaViewHolder extends RecyclerView.ViewHolder {
private TextView txtUserAlphabet, timer;
private ImageView play;
private SeekBar seekBar;
ProgressBar progressBar;
RelativeLayout media_chat;
Chat chat = null;
public MyChatMediaViewHolder(View itemView) {
super(itemView);
play = (ImageView) itemView.findViewById(R.id.play);
seekBar = (SeekBar) itemView.findViewById(R.id.seekbar);
txtUserAlphabet = (TextView) itemView.findViewById(R.id.text_view_user_alphabet);
progressBar = (ProgressBar) itemView.findViewById(R.id.progressUpdate);
media_chat = (RelativeLayout) itemView.findViewById(R.id.chat_media);
timer = (TextView) itemView.findViewById(R.id.timer);
Log.e("TAG111", "bindData: ");
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isPlay = !isPlay;
//Handling for background selection state changed
int previousSelectState=mSelectedItemPosition;
mSelectedItemPosition = getAdapterPosition();
//notify previous selected item
notifyItemChanged(previousSelectState);
//notify new selected Item
notifyItemChanged(mSelectedItemPosition);
}
});
}
public void bindData(Chat chat, int currentPosition) {
this.chat = chat;
MediaPlayer mediaPlayer = new MediaPlayer();
MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
try {
mediaPlayer.setDataSource(chat.mediaUrlLocal);
metaRetriever.setDataSource(chat.mediaUrlLocal);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
String duration =
metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long dur = Long.parseLong(duration);
String seconds = String.valueOf((dur % 60000) / 1000);
String minutes = String.valueOf(dur / 60000);
String out = minutes + ":" + seconds;
timer.setText(out);
if(currentPosition == mSelectedItemPosition) {
Log.e("pause", "bindData: " + mediaPlayer.isPlaying());
if(isPlay) {
mediaPlayer.start();
play.setImageResource(android.R.drawable.ic_media_pause);
} else {
mediaPlayer.pause();
play.setImageResource(android.R.drawable.ic_media_play);
}
} else {
play.setImageResource(android.R.drawable.ic_media_play);
}
}
}
我认为这里的问题是:每次都会创建新的MediaPlayer
实例
单击播放按钮,所以当我尝试暂停时,会再次创建一个从未启动的新媒体播放器。
所以问题是:我应该在哪里创建新的MediaPlayer实例?
答案 0 :(得分:1)
我认为最好的解决方案(如果你一次只需要播放一个音频)就是在RecyclerView.Adapter中只保留一个MediaPlayer实例,你也可以保留一个地图,其中键是位置和值是一个简单的类包含:flag - isPlaying,持续时间(当你播放你的歌曲并暂停它时,你不想从头开始但是从你暂停的地方开始),等等。所以当你上下滚动时你会能够保留播放/暂停的观看状态。
答案 1 :(得分:1)
首先,RecyclerView.Adapter
的目的是为了扩大您的观点,不应该在此处编写您的业务逻辑。
其次,您应该只使用一个媒体播放器实例。您应该在Activity
或Fragment
。
在Activity
或Fragment
中创建一个接口工具,并将其引用传递给您的适配器。每当您想要播放音频时,您将使用界面将音频文件路径或流传输到Activity
或Fragment
,重置或释放媒体播放器并播放音频。