Я сделал приложение чата, где использовал RecyclerView
. Сообщения могут быть текстовыми или аудиосообщениями. Все работает нормально, за исключением случаев, когда я изменяю текст таймера на TextView
(для компоновки аудиоплеера, который я сделал), от того, как долго воспроизводится песня. Я делаю это в Runnable
. Но когда я прокручиваю RecyclerView
, таймер TextView
меняет текст в случайном положении.RecyclerView случайное изменение положения при прокрутке
Вот как я изменяю TextView
текст:
public void updateTimer(final int position) {
View view = mRecyclerViewChat.getLayoutManager().findViewByPosition(position);
timer = (TextView) view.findViewById(R.id.timer);
r = new Runnable() {
public void run() {
int currentDuration;
if (player.isPlaying()) {
currentDuration = player.getCurrentPosition();
timer.setText("" + milliSecondsToTimer((long) currentDuration));
timer.postDelayed(this, 1000);
} else {
timer.removeCallbacks(this);
}
}
};
timer.post(r);
}
position
Здесь есть значение позиции я получаю от onBindViewHolder
.
EDIT
Вот onBindViewHolder
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (TextUtils.equals(mChats.get(position).senderUid,
FirebaseAuth.getInstance().getCurrentUser().getUid())) {
if (mChats.get(position).mediaUrlLocal == null) {
configureMyChatViewHolder((MyChatViewHolder) holder, position);
} else {
configureMyChatMediaViewHolder((MyChatMediaViewHolder) holder, position);
}
} else {
if (mChats.get(position).mediaUrlLocal == null) {
configureOtherChatViewHolder((OtherChatViewHolder) holder, position);
} else {
configureOtherChatMediaViewHolder((OtherChatMediaViewHolder) holder, position);
}
}
}
и вот playMedia
метод, который вызывается из configureMyChatMediaViewHolder
метода:
private void playMyMedia(final MyChatMediaViewHolder myChatViewHolder, final Chat chat, final int position) {
MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
metaRetriever.setDataSource(chat.mediaUrlLocal);
String duration =
metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long dur = Long.parseLong(duration);
String seconds = String.valueOf((dur % 60000)/1000);
String minutes = String.valueOf(dur/60000);
String out = minutes + ":" + seconds;
myChatViewHolder.timer.setText(out);
if (chat.isPlay) {
myChatViewHolder.play.setVisibility(View.GONE);
myChatViewHolder.pause.setVisibility(View.VISIBLE);
} else {
myChatViewHolder.play.setVisibility(View.VISIBLE);
myChatViewHolder.pause.setVisibility(View.GONE);
}
myChatViewHolder.play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
chat.isPlay = !chat.isPlay;
if (previousChat != position && previousChat != -1) {
previousChatObj = mChats.get(previousChat);
}
previousChat = position;
myChatViewHolder.play.setVisibility(View.GONE);
myChatViewHolder.pause.setVisibility(View.VISIBLE);
callback.onPlayClickListener(chat, previousChatObj, position);
}
});
myChatViewHolder.pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
chat.isPlay = !chat.isPlay;
myChatViewHolder.play.setVisibility(View.VISIBLE);
myChatViewHolder.pause.setVisibility(View.GONE);
callback.onPauseClickListener(chat, position);
}
});
}
У меня есть только один медиа экземпляр проигрывателя в фрагмент, из которого установлен адаптер для чата.
Просьба представить вам 'ViewHolder' и' onBindViewHolder() 'реализации. Использование 'final int position', как вы делаете, неверно - вы никогда не должны кэшировать позицию RecyclerView. Также неясно, когда каждый раз просматривайте таймер TextView - он должен храниться в ViedHolder и т. Д. –
Я отправил ответ, пожалуйста, дайте мне знать, если это поможет –
Еще одна идея: после утилизации ваш TextView все еще может иметь Бегуны прикреплены к нему. поэтому ** перед ** вы вызываете 'myChatViewHolder.timer.setText (out);' call 'myChatViewHolder.timer.removeCallbacks (myChatViewHolder.timer.getTag());'. В 'updateTimer()' добавить последнюю строку 'timer.setTag (r)' –