如何在Recyclview Android上使用带有seekbar的音频? [英] How to use the Audio with seekbar on Recyclview android?
问题描述
我正在使用 Recyclview
上的音频列表,并且工作正常,这意味着我可以在 Recyclview
上播放音频文件.
由于我在 Recyclview
上使用音频文件中的 Seekbar
时,问题是当我滚动 items's of Recyclview Seekbar
正在更改(我正在使用搜索栏来查看音频文件的播放进度.)
当我滚动 Recyclview
时,我不希望更改 Recyclview
的其他 Seekbar
项的内容>
请检查我的代码,在 Recyclview
的 onBindViewHolder
中,我正在使用以下代码,请检查一下.
((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);
}
});
我在 SO 上访问了以下站点,但未获得相关的解决方案
1.第一链接
2.第二个链接
我们可以使用 setTag()
和 getTag()
摆脱此问题.我在上面的代码中使用了 setTag()
.请检查一次.
尽管如此,我假设您只询问了正确的SeekBar
更新(,因为您没有分片完整的源代码)很快您将面临与Adapter
实现相关的以下问题:
-
MediaPlayer
完成音频播放后,如何删除seekBar更新程序? - 活动暂停后如何释放
MediaPlayer
? - 匿名
View.OnClickListener
和Runnable
在每次onBindViewHolder
呼叫中分配.如何减少不必要的分配?
您可以在此处找到完整的工作解决方案- GitHub
以下消息源试图解决所有上述问题.根据您的命名法假定某些数据结构/类.
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 {
}
}
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.
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 {
}
}
这篇关于如何在Recyclview Android上使用带有seekbar的音频?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!