Можно ли получить положение представлений внутри ViewHolder для RecyclerView?
Имеющийся у меня ViewHolder содержит представления, необходимые для каждого элемента моего RecycleView: два TextView, PlayPauseView и AppCompatSeekBar. В конструкторе я инициализировал их для их идентификаторов моего макета и готов к тому, чтобы мой класс Adapter расширил его. Проблема в том, что у меня есть этот PlayPauseView, который нужно переключать в правильной позиции, чтобы он функционировал правильно, потому что если я нажимаю вид в другой позиции, предыдущая позиция все еще переключается. Вот изображение для лучшего понимания.
Желтый цвет означает, что он в данный момент воспроизводится, но два не могут воспроизводиться одновременно, поэтому я надеялся получить позицию представления внутри элемента RecyclerView.
Это из класса Holder
TextView mInstrumentalName, mProducer;
PlayPauseView mPlayButton; // Need to add pause/stop
AppCompatSeekBar mMusicSeekbar;
ItemClickListener itemClickListener;
public TrackHolder(View itemView) {
super(itemView);
mInstrumentalName = (TextView) itemView.findViewById(R.id.instrumental_name);
mProducer = (TextView) itemView.findViewById(R.id.producer);
mPlayButton = (PlayPauseView) itemView.findViewById(R.id.play_pause);
mMusicSeekbar = (AppCompatSeekBar) itemView.findViewById(R.id.music_seekbar);
itemView.setOnClickListener(this);
}
Это из класса Адаптер
@Override
public void onBindViewHolder(@NonNull final TrackHolder holder, final int position) {
holder.mInstrumentalName.setText(tracks.get(position).getInstrumentalName());
holder.mProducer.setText(tracks.get(position).getProducer());
holder.mPlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
holder.mPlayButton.toggle();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
if (mediaPlayer.isPlaying()) {
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
} else {
try {
mediaPlayer.setDataSource(tracks.get(position).getMusicLink());
previous_link = tracks.get(position).getMusicLink();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
}
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onItemClick(View v, int pos) {
Toast.makeText(context, Integer.toString(tracks.size()), Toast.LENGTH_SHORT).show();
}
});
}
2 ответа
Если вы хотите получить позицию в своем классе держателя вида, вы можете позвонить getAdapterPosition()
внутри вашего класса. это вернет вам нажатую позицию в классе держателя просмотра
Я наконец нашел решение. Поэтому вместо того, чтобы сосредоточиться на представлениях внутри ViewHolder, я обновил / обновил весь элемент в RecyclerView, то есть он обновит состояние переключения предыдущего элемента. Вот фрагмент кода, если у кого-то в будущем возникнут проблемы по тому же вопросу.
private int start_notifying = 0;
private int previous_pos = -1;
Так что начните уведомление с 0, потому что вы не хотите обновлять элемент, пока не нажмете кнопку воспроизведения хотя бы один раз, и не установите текущую позицию, чтобы стать предыдущей, когда вы хотите нажать другой элемент списка. Затем вы увеличиваете, чтобы вы могли начать обновление элементов для следующего нажатого элемента. Использование notifyItemChanged (previous_pos) обновило элемент предыдущей позиции, которая была нажата, в результате чего кнопка воспроизведения вернулась в свое нормальное состояние.
if (start_notifying > 0) {
notifyItemChanged(previous_pos);
previous_pos = position;
} else {
previous_pos = holder.getAdapterPosition();
Log.d("previous_pos", Integer.toString(holder.getAdapterPosition()));
start_notifying++;
}