我已经创建了一个聊天应用程序,并使用了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
获得位置值。
编辑
这里是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);'调用'myChatViewHolder.timer.removeCallbacks(myChatViewHolder.timer.getTag());'。在'updateTimer()'添加最后一行'timer.setTag(r)' –