我需要一些帮助,我想制作一个包含每个项目音频的循环视图,如何在按下播放按钮时播放音频并将进度设置为搜索条,同时暂停其他声音并转换播放按钮进行播放所有行中的模式除了播放一个处于暂停模式 例如或facebook messenger中的聊天
这是我的代码: MyAdapter.class
private List<String> positions = new ArrayList<>();
public myAdapter(Activity activity, ArrayList<Tweet> list) {
this.activity = activity;
this.list = list;
mPlayer = new MediaPlayer();
}
public void onBindViewHolder(final viewHolder holder, final int position) {
if (!positions.contains(String.valueOf(position)))
positions.add(String.valueOf(position));
}
}
viewHolder.class
public class viewHolder extends RecyclerView.ViewHolder implements
SeekBar.OnSeekBarChangeListener, View.OnClickListener {
LinearLayout parentPanel;
int viewType;
private RelativeLayout pauseLayout, playLayout;
private ImageView pauseIcon, playIcon;
private SeekBar seekBar;
private TextView periodTime;
AudioCallbacks mAudioCallbacks;
private int last_position;
viewHolder(final View itemView, int viewType) {
super(itemView);
this.viewType = viewType;
playLayout = (RelativeLayout) itemView.findViewById(R.id.play_layout);
pauseLayout = (RelativeLayout) itemView.findViewById(R.id.pause_layout);
playIcon = (ImageView) itemView.findViewById(R.id.play_icon);
pauseIcon = (ImageView) itemView.findViewById(R.id.pause_icon);
seekBar = (SeekBar) itemView.findViewById(R.id.seekBar);
periodTime = (TextView) itemView.findViewById(R.id.period_time);
seekBar.setOnSeekBarChangeListener(this);
playLayout.setOnClickListener(this);
pauseLayout.setOnClickListener(this);
mAudioCallbacks = new AudioCallbacks() {
@Override
public void onUpdate(int percentage) {
seekBar.setProgress(percentage);
if (percentage == 100)
mAudioCallbacks.onStop();
}
@Override
public void onPause() {
Log.i("on pause audio", " pause");
}
@Override
public void onStop() {
Log.i("on stop audio", " stop");
stopPlayingAudio();
}
};
}
void stopPlayingAudio() {
if (mPlayer != null) {
if (mPlayer.isPlaying()) {
updateAudioProgressBar();
mPlayer.stop();
mPlayer.reset();
seekBar.setProgress(0);
playLayout.setVisibility(View.VISIBLE);
pauseLayout.setVisibility(View.GONE);
}
}
}
void pausePlayingAudio() {
if (mPlayer != null) {
if (mPlayer.isPlaying()) {
mPlayer.pause();
updateAudioProgressBar();
mAudioCallbacks.onPause();
}
}
}
void playingAudio(Tweet message) {
updateAudioProgressBar();
if (mPlayer != null) {
try {
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(message.getAudioUrl());
mPlayer.prepare();
mPlayer.start();
periodTime.setVisibility(View.VISIBLE);
periodTime.setText(String.valueOf(message.getAudioDuration()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
void updateAudioProgressBar() {
durationHandler.postDelayed(mUpdateTimeTask, 100);
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
try {
if (mPlayer.isPlaying()) {
long totalDuration = mPlayer.getDuration();
long currentDuration = mPlayer.getCurrentPosition();
int progress = Utils.getProgressPercentage(currentDuration, totalDuration);
mAudioCallbacks.onUpdate(progress);
periodTime.setText(Utils.getFileTime(currentDuration));
durationHandler.postDelayed(this, 100);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
durationHandler.removeCallbacks(mUpdateTimeTask);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int totalDuration = mPlayer.getDuration();
int currentPosition = Utils.progressToTimer(seekBar.getProgress(), totalDuration);
mPlayer.seekTo(currentPosition);
updateAudioProgressBar();
}
@Override
public void onClick(View view) {
Log.e("getAdapterPosition()L", last_position + " /");
for (String pos : positions) {
if (!pos.equals(String.valueOf(getAdapterPosition())))
notifyItemChanged(Integer.parseInt(pos));
}
last_position = getAdapterPosition();
Log.e("getAdapterPosition()F", last_position + " /");
Tweet message = list.get(getAdapterPosition());
switch (view.getId()) {
case R.id.pause_layout:
playLayout.setVisibility(View.VISIBLE);
pauseLayout.setVisibility(View.GONE);
pausePlayingAudio();
break;
case R.id.play_layout:
playLayout.setVisibility(View.GONE);
pauseLayout.setVisibility(View.VISIBLE);
mAudioCallbacks.onStop();
playingAudio(message);
break;
}
}
}
public interface AudioCallbacks {
void onUpdate(int percentage);
void onPause();
void onStop();
}
此代码的问题是:
有人可以帮助我吗?
答案 0 :(得分:10)
从MediaPlayer
单元格控制和更新RecyclerView
的进度非常棘手。您的解决方案未正确更新onBindViewHolder
调用中的视图状态,这是您遇到的所有问题的根本原因。人们应该记住的其他几点注意事项如下:
xxxListener
中对Runnable
,onBindViewHolder
进行匿名分配,即ViewHolder
可用于实现xxxListener
接口等。以下来源显示Adapter
private class AudioItemAdapter extends RecyclerView.Adapter<AudioItemAdapter.AudioItemsViewHolder> {
private MediaPlayer mediaPlayer;
private List<AudioItem> audioItems;
private int currentPlayingPosition;
private SeekBarUpdater seekBarUpdater;
private AudioItemsViewHolder playingHolder;
AudioItemAdapter(List<AudioItem> audioItems) {
this.audioItems = audioItems;
this.currentPlayingPosition = -1;
seekBarUpdater = new SeekBarUpdater();
}
@Override
public AudioItemsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new AudioItemsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false));
}
@Override
public void onBindViewHolder(AudioItemsViewHolder holder, int position) {
if (position == currentPlayingPosition) {
playingHolder = holder;
updatePlayingView();
} else {
updateNonPlayingView(holder);
}
}
@Override
public void onViewRecycled(AudioItemsViewHolder holder) {
super.onViewRecycled(holder);
if (currentPlayingPosition == holder.getAdapterPosition()) {
updateNonPlayingView(playingHolder);
playingHolder = null;
}
}
private void updateNonPlayingView(AudioItemsViewHolder holder) {
holder.sbProgress.removeCallbacks(seekBarUpdater);
holder.sbProgress.setEnabled(false);
holder.sbProgress.setProgress(0);
holder.ivPlayPause.setImageResource(R.drawable.ic_play_arrow);
}
private void updatePlayingView() {
playingHolder.sbProgress.setMax(mediaPlayer.getDuration());
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.setEnabled(true);
if (mediaPlayer.isPlaying()) {
playingHolder.sbProgress.postDelayed(seekBarUpdater, 100);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_pause);
} else {
playingHolder.sbProgress.removeCallbacks(seekBarUpdater);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_play_arrow);
}
}
void stopPlayer() {
if (null != mediaPlayer) {
releaseMediaPlayer();
}
}
private class SeekBarUpdater implements Runnable {
@Override
public void run() {
if (null != playingHolder) {
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.postDelayed(this, 100);
}
}
}
@Override
public int getItemCount() {
return audioItems.size();
}
class AudioItemsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
SeekBar sbProgress;
ImageView ivPlayPause;
AudioItemsViewHolder(View itemView) {
super(itemView);
ivPlayPause = (ImageView) itemView.findViewById(R.id.ivPlayPause);
ivPlayPause.setOnClickListener(this);
sbProgress = (SeekBar) itemView.findViewById(R.id.sbProgress);
sbProgress.setOnSeekBarChangeListener(this);
}
@Override
public void onClick(View v) {
if (getAdapterPosition() == currentPlayingPosition) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
mediaPlayer.start();
}
} else {
currentPlayingPosition = getAdapterPosition();
if (mediaPlayer != null) {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
mediaPlayer.release();
}
playingHolder = this;
startMediaPlayer(audioItems.get(currentPlayingPosition).audioResId);
}
updatePlayingView();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mediaPlayer.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
private void startMediaPlayer(int audioResId) {
mediaPlayer = MediaPlayer.create(getApplicationContext(), audioResId);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
mediaPlayer.start();
}
private void releaseMediaPlayer() {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
mediaPlayer.release();
mediaPlayer = null;
currentPlayingPosition = -1;
}
}
您可以在此处找到完整的工作解决方案 - GitHub