如何在 Recyclerview android 中使用带搜索栏的音频?
How to use the Audio with seekbar on Recyclview android?
我正在 Recyclview
上使用音频列表,它工作正常意味着我可以在 上播放音频文件Recyclview
.
因为我在 Recyclview
上使用 Seekbar
和我的音频文件,问题是生成当我滚动 Recyclview
时另一个 items's of Recyclview Seekbar
正在改变(Seekbar 我正在使用进度音频文件播放。)
我想要 Recyclview
的其他 Seekbar
项在我滚动Recyclview
请检查我的代码,在我的 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 .First Link
2. Second Link
我们可以使用 setTag()
和 getTag()
来摆脱这个问题吗?我在上面的代码中使用了 setTag()
。请检查一次。
尽管您只询问了正确的 SeekBar
更新,但我假设(因为您还没有分片完整的源代码)很快您将面临以下问题链接到 Adapter
实现:
- 如何在
MediaPlayer
完成音频播放后删除 seekBar 更新程序?
- activity暂停时如何释放
MediaPlayer
?
- 匿名
View.OnClickListener
s 和 Runnable
s 被分配到 every onBindViewHolder
呼叫。我如何尽量减少他们不必要的分配?
您可以在此处找到完整的工作解决方案 - GitHub
以下来源试图解决上述所有问题。某些数据 structures/classes 是根据您的命名法假定的。
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
上使用音频列表,它工作正常意味着我可以在 上播放音频文件Recyclview
.
因为我在 Recyclview
上使用 Seekbar
和我的音频文件,问题是生成当我滚动 Recyclview
时另一个 items's of Recyclview Seekbar
正在改变(Seekbar 我正在使用进度音频文件播放。)
我想要 Recyclview
的其他 Seekbar
项在我滚动Recyclview
请检查我的代码,在我的 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 .First Link
2. Second Link
我们可以使用 setTag()
和 getTag()
来摆脱这个问题吗?我在上面的代码中使用了 setTag()
。请检查一次。
尽管您只询问了正确的 SeekBar
更新,但我假设(因为您还没有分片完整的源代码)很快您将面临以下问题链接到 Adapter
实现:
- 如何在
MediaPlayer
完成音频播放后删除 seekBar 更新程序? - activity暂停时如何释放
MediaPlayer
? - 匿名
View.OnClickListener
s 和Runnable
s 被分配到 everyonBindViewHolder
呼叫。我如何尽量减少他们不必要的分配?
您可以在此处找到完整的工作解决方案 - GitHub
以下来源试图解决上述所有问题。某些数据 structures/classes 是根据您的命名法假定的。
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 {
}
}