问题
I am using the lists of audio on my Recyclview
and it is working correct means I am able to play the audio file on my Recyclview
.
As i am using the Seekbar
with my audio file on my Recyclview
, the problem is generating that when i am scrolling the Recyclview
the other items's of Recyclview Seekbar
is changing (Seekbar i am using for the progress of the audio file play.)
What i want that other Seekbar
item of Recyclview
sholud not be change when i scroll the Recyclview
Please check my code for it ,Inside the onBindViewHolder
for my Recyclview
, i am using the following code, please check it once.
((MyAudioChat) holder).sbMyAudio.setTag(position);
((MyAudioChat) holder).imgPlayAudio.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((MyAudioChat) holder).sbMyAudio.removeCallbacks(null);
((MyAudioChat) holder).sbMyAudio.setProgress(0);
if (mediaPlayer == null) {
mediaPlayer();
((MyAudioChat) holder).sbMyAudio.setMax(mediaPlayer.getDuration());
} else {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer();
((MyAudioChat) holder).sbMyAudio.setMax(mediaPlayer.getDuration());
}
((MyAudioChat) holder).sbMyAudio.getTag();
((MyAudioChat) holder).sbMyAudio.setMax(mediaPlayer.getDuration()); // Set the Maximum range of the
((MyAudioChat) holder).sbMyAudio.setProgress(mediaPlayer.getCurrentPosition());// set current progress to song's
Runnable moveSeekBarThread = new Runnable() {
public void run() {
if (mediaPlayer.isPlaying()) {
int mediaPos_new = mediaPlayer.getCurrentPosition();
int mediaMax_new = mediaPlayer.getDuration();
((MyAudioChat) holder).sbMyAudio.setMax(mediaMax_new);
((MyAudioChat) holder).sbMyAudio.setProgress(mediaPos_new);
((MyAudioChat) holder).sbMyAudio.postDelayed(this, 100); //Looping the thread after 0.1 second
((MyAudioChat) holder).sbMyAudio.getTag();
}
}
};
((MyAudioChat) holder).sbMyAudio.removeCallbacks(moveSeekBarThread);
((MyAudioChat) holder).sbMyAudio.postDelayed(moveSeekBarThread, 100);
}
});
I have visited the following site on SO but did not get the relevant solution
1 .First Link
2. Second Link
Can we use the setTag()
and getTag()
to get rid of from this problem. I have used the setTag()
on my above code. Please check it once.
回答1:
Although, you have asked only about correct SeekBar
updates, I am assuming (because you haven't shard complete source) that soon you will face following issues which are linked to the Adapter
implementation:
- How do I remove the seekBar updater, when
MediaPlayer
completes the playback of audio? - How do I release the
MediaPlayer
when activity is paused? - Anonymous
View.OnClickListener
s andRunnable
s are being allocated on everyonBindViewHolder
call. How do I minimize their unnecessary allocation?
You can find complete working solution here - GitHub
Following source tries to fix all above issues. Certain data structures/classes are assumed based on your nomenclature.
public class MainActivity extends Activity {
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this));
AudioChat audioChats[] = new AudioChat[128];
rv.setAdapter(new MyAdapter(Arrays.asList(audioChats)));
}
@Override
protected void onPause() {
super.onPause();
if (null != mediaPlayer) {
mediaPlayer.release();
mediaPlayer = null;
}
}
private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyAudioChat> {
private List<AudioChat> audioChats;
private int currentPlayingPosition;
private SeekBarUpdater seekBarUpdater;
MyAdapter(List<AudioChat> audioChats) {
this.audioChats = audioChats;
this.currentPlayingPosition = -1;
seekBarUpdater = new SeekBarUpdater();
}
@Override
public MyAudioChat onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyAudioChat(LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false));
}
@Override
public void onBindViewHolder(MyAudioChat holder, int position) {
if (position == currentPlayingPosition) {
seekBarUpdater.playingHolder = holder;
holder.sbMyAudio.post(seekBarUpdater);
} else {
holder.sbMyAudio.removeCallbacks(seekBarUpdater);
holder.sbMyAudio.setProgress(0);
}
}
private class SeekBarUpdater implements Runnable {
MyAudioChat playingHolder;
@Override
public void run() {
if (null != mediaPlayer && playingHolder.getAdapterPosition() == currentPlayingPosition) {
playingHolder.sbMyAudio.setMax(mediaPlayer.getDuration());
playingHolder.sbMyAudio.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbMyAudio.postDelayed(this, 100);
} else {
playingHolder.sbMyAudio.removeCallbacks(seekBarUpdater);
}
}
}
@Override
public int getItemCount() {
return audioChats.size();
}
class MyAudioChat extends RecyclerView.ViewHolder implements View.OnClickListener {
SeekBar sbMyAudio;
ImageView imgPlayAudio;
MyAudioChat(View itemView) {
super(itemView);
imgPlayAudio = (ImageView) itemView.findViewById(R.id.imgPlayAudio);
imgPlayAudio.setOnClickListener(this);
sbMyAudio = (SeekBar) itemView.findViewById(R.id.sbMyAudio);
}
@Override
public void onClick(View v) {
currentPlayingPosition = getAdapterPosition();
if (mediaPlayer != null) {
if (null != seekBarUpdater.playingHolder) {
seekBarUpdater.playingHolder.sbMyAudio.removeCallbacks(seekBarUpdater);
seekBarUpdater.playingHolder.sbMyAudio.setProgress(0);
}
mediaPlayer.release();
}
seekBarUpdater.playingHolder = this;
startMediaPlayer();
sbMyAudio.setMax(mediaPlayer.getDuration());
sbMyAudio.post(seekBarUpdater);
}
}
private void startMediaPlayer() {
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.mp3);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
seekBarUpdater.playingHolder.sbMyAudio.removeCallbacks(seekBarUpdater);
seekBarUpdater.playingHolder.sbMyAudio.setProgress(0);
mediaPlayer.release();
mediaPlayer = null;
currentPlayingPosition = -1;
}
});
mediaPlayer.start();
}
}
private class AudioChat {
}
}
来源:https://stackoverflow.com/questions/46150170/how-to-use-the-audio-with-seekbar-on-recyclview-android