Так же, как у держателя представления есть метод getAdapterPosition (), я хочу написать свой собственный setAdapterPosition () для держателя представления (которого не существует).
Над чем я работаю ?
В настоящее время я работаю над проектом, в котором я должен перечислить 10 песен в виде представления ресайклера, а затем воспроизвести их, если нажата какая-либо конкретная песня. Каждый элемент списка содержит название песни, панель поиска и кнопку воспроизведения.
Я реализовал эту часть, добавив все элементы управления медиаплеера внутри класса адаптера.
Что делать Я хочу?
В настоящее время в этой модели используется mediaPlayer.setLooping (true), так что, как только песня заканчивается, она продолжает зацикливаться, пока не будет нажата другая песня для воспроизведения.
Теперь я хочу расширить эту модель до версии с «автовоспроизведением», чтобы, как только песня закончилась, воспроизводилась следующая песня
В чем проблема?
Прогресс seekBar и переход изображения playButton в изображение pauseButton происходили с вызовом
viewHolder.seekBar.setProgress(...)
viewHolder.playButton.setImageDrawable(...)
Так как это происходило на
viewHolder.itemView.setOnClickListener(...)
, как только была нажата новая песня, обновлялись изображения seekBar и playButton.
Теперь, когда песня завершена, я не хочу, чтобы пользователь щелкал следующую песню, чтобы воспроизвести ее. Я хочу, чтобы он воспроизводился автоматически, но я не могу понять, как мне изменить положение myViewHolder соответствующим образом.
Предположим, что песня 0 закончила воспроизведение, а песня 1 начала играть, viewHolder.getAdapterPosition () по-прежнему возвращает 0 вместо из 1. Следовательно, обновляется seekBar & playButton песни 0, а не песни 1.
Я хочу иметь возможность делать что-то вроде этого
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
int nextSongPosition, currentSongPosition;
currentSongPosition = viewHolder.getAdapterPosition();
if(currentSongPosition==(songs.size()-1)){
nextSongPosition = 0;
//do some miracle so that viewHolder.getAdapterPosition() now shows 0 instead of currentSongPosition
}else{
nextSongPosition = currentSongPosition + 1;
//do some miracle so that viewHolder.getAdapterPosition() now shows nextSongPosition instead of the currentSongPosition;
}
}
});
Как ясно из вопроса оператор, я хочу реализовать что-то похожее на setAdapterPosition (), которого не существует.
EDIT 1
onBindViewHolder Code:
@Override
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, int i) {
Song song = songs.get(i);
viewHolder.itemView.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
audioManager = (AudioManager) Objects.requireNonNull(context).getSystemService(Context.AUDIO_SERVICE);
if(mediaPlayer.isPlaying()){
pauseMediaPlayer(viewHolder);
}else{
StorageReference storageRef = FirebaseStorage.getInstance().getReference("Songs");
StorageReference dateRef = storageRef.child(song.getStoredAs());
dateRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
try {
mediaPlayer.setDataSource(uri.toString());
mediaPlayer.prepare();
viewHolder.seekBar.setMax(mediaPlayer.getDuration() / 1000);
mSeekbarUpdateHandler = new Handler();
mUpdateSeekbar = new Runnable() {
@Override
public void run() {
if (viewHolder.seekBar != null && mediaPlayer != null) {
try{
viewHolder.seekBar.setProgress(mediaPlayer.getCurrentPosition() / 1000);
mSeekbarUpdateHandler.postDelayed(this, 50);
} catch(IllegalStateException e){
Log.i("Exception",e.toString());
}
}
}
};
viewHolder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser && mediaPlayer != null)
mediaPlayer.seekTo( progress * 1000);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
startMediaPlayer(viewHolder);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
Log.i("Song Loading Error", exception.toString());
}
});
}
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
int nextSongPosition, currentSongPosition;
currentSongPosition = viewHolder.getAdapterPosition();
if(currentSongPosition==(songs.size()-1)){
nextSongPosition = 0;
//do some miracle so that viewHolder.getAdapterPosition() now shows 0 instead of currentSongPosition
}else{
nextSongPosition = currentSongPosition + 1;
//do some miracle so that viewHolder.getAdapterPosition() now shows nextSongPosition instead of the currentSongPosition;
}
}
});
}
pauseMediaPlayer (..) и startMediaPlayer (..) Код:
private void pauseMediaPlayer(ViewHolder viewHolder) {
int result = audioManager.requestAudioFocus(this, AudioManager.USE_DEFAULT_STREAM_TYPE, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
isSongPlaying = false;
viewHolder.playButton.setImageResource(R.drawable.play_button);
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}
}
private void startMediaPlayer(ViewHolder viewHolder) {
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
isSongPlaying = true;
viewHolder.playButton.setImageResource(R.drawable.pause_button);
if (mediaPlayer != null) {
//mediaPlayer.setLooping(true);
mediaPlayer.start();
}
mSeekbarUpdateHandler.postDelayed(mUpdateSeekbar, 0);
}
}