У меня есть активность Android, которая содержит RecyclerView, в основном я создаю приложение для музыкального плеера. Здесь предыдущая кнопка песни должна найти предыдущий элемент RecyclerView и выполнить щелчок по нему (это будет играть песню), для этого, когда я использую recyclerView.getChildAt()
, она возвращает ноль, что приводит к ошибке.
Вот код для onClickListener
предыдущей кнопки ...
prevSong_bottomSheet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// We start by checking if this is the first song or not!
if (songIndex.getCurrentIndex() == 0) {
Toast.makeText(MainActivity.this, "Nothing to play before this", Toast.LENGTH_SHORT).show();
// Now, this simply return as we don't want to execute any of the following code!
return;
}
Log.d(DEBUG_MESSAGE, "Original song index: " + songIndex.getCurrentIndex());
try {
// First, as we know that we'll be playing the previous audio, we start by decrementing
// the value inside `SongIndex`.
songIndex.prevSongPlayed();
// As the value inside `SongIndex` has been decremented, we use the same here!
View parentView = recyclerView.getChildAt(songIndex.getCurrentIndex());
// Now we extract the action button associated with this particular view!
Button tempButton = parentView.findViewById(R.id.music_actionButton);
// Now that we've got the button, instead of calling `startSong()` directly, we'll
// perform a click on the button, this way if we decide to perform some other action (in the future)
// once the user clicks that button, the action would still be valid!
tempButton.performClick();
Log.d(DEBUG_MESSAGE, "Previous song played successfully!");
} catch (NullPointerException e) {
// Lastly, if any error occurred in the above code, in the first line itself, we
// have already decremented SongIndex in the first line itself, thus, we increment
// it here to balance it out!
//songIndex.nextSongPlayed();
Log.d(DEBUG_MESSAGE, e.getLocalizedMessage() + "\n\n\n\n\n\n");
e.printStackTrace();
Log.d(DEBUG_MESSAGE, "Final song index: " + songIndex.getCurrentIndex());
}
}
});
Во время выполнения вышеуказанного кода он работает отлично, пока следующий элемент RecyclerView находится на экране, однако начинает возвращать ноль, когда представление находится за пределами экрана!
Да, я знаю, что RecyclerView уничтожит элементы, находящиеся за пределами экрана (или даже не создаст их). Чтобы обойти это, я попытался использовать recyclerView.scrollToPosition()
, даже после этого он возвращает ноль. Я попытался прокрутить вверх до позиции предыдущего элемента и даже на 2 или 3 позиции над ним, но getChildAt()
возвращает ноль. Помимо этого, я также пытался заблокировать основной поток, чтобы дождаться прокрутки RecyclerView вверх (используя бесконечный цикл), даже после того, как getChildAt()
вернет ноль.
Как мне решить эту проблему?
P.S. songIndex
- это класс, который должен следить за положением песни, которая воспроизводится в данный момент. Вот код для этого (на всякий случай):
private class SongIndex {
/**
* This class is used to keep a track as to which song is being played currently, the data member
* created inside this class would be regularly updated using the functions defined below!
* Thus, this class will be used at various instances inside the program to know about the
* index of the song (inside the RecyclerView) which is being played currently!
*/
private int currentSongIndex;
public int getCurrentIndex() {
return currentSongIndex;
}
public void setCurrentSongIndex(int currentSongIndex) {
this.currentSongIndex = currentSongIndex;
}
public void nextSongPlayed() {
currentSongIndex++;
}
public void prevSongPlayed() {
currentSongIndex--;
}
}
PSS Еще одна вещь, которую я пытался решить, заключалась в том, что, когда я достиг верхней части экрана (над ними было бы больше элементов, но ни один из них не был бы на экране, то есть RecyclerView, вероятно, уничтожил бы их), после этого я прокручивал вручную, чтобы текущая воспроизводимая песня была в середине экрана (теперь у нее есть элементы над ней), даже сейчас, когда я попробовал предыдущую кнопку, я все равно каким-то образом оказался внутри catch
часть: (