Hi Community,
我正在开发类似应用程序的应用程序。我正面临着一个问题 滚动项目时回收视图中的问题。问题是均匀的 特定于音频文件本身。这些文件与播放无关 项目数据位置。请帮我解决这个问题。
MyAdapterClass:
@Override
public void onBindViewHolder(SwappingHolder holder, int position) {
MessageDetails messageData = messagesList.get(position);
if (messageData != null) {
switch (messageData.getMessageType()) {
case MessageDetails.MESSAGE_TEXT_TYPE:
TextTypeViewHolder textViewHolder = (TextTypeViewHolder) holder;
textViewHolder.updateView(messageData);
break;
case MessageDetails.MESSAGE_IMAGE_TYPE:
ImageTypeViewHolder imageViewHolder = (ImageTypeViewHolder) holder;
imageViewHolder.updateImageFile(messageData);
break;
case MessageDetails.MESSAGE_AUDIO_TYPE:
AudioTypeViewHolder audioHolder = (AudioTypeViewHolder) holder;
audioHolder.initializeAudioPlayer(messageData);
break;
case MessageDetails.MESSAGE_VIDEO_TYPE:
VideoTypeViewHolder videoHolder = (VideoTypeViewHolder) holder;
videoHolder.updateVideoMessage(messageData);
break;
case MessageDetails.MESSAGE_LOCATION_TYPE:
MapTypeHolder mapHolder = (MapTypeHolder) holder;
mapHolder.loadMapThumbView(messageData);
break;
case MessageDetails.MESSAGE_CONTACT_TYPE:
ContactsTypeHolder contactsHolder = (ContactsTypeHolder) holder;
contactsHolder.setContactData(messageData);
break;
case MessageDetails.MESSAGE_FILE_TYPE:
FileTypeHolder fileTypeHolder = (FileTypeHolder)holder;
fileTypeHolder.updateFileData(messageData);
}
}
}
MyHolderClass:
public class AudioTypeViewHolder extends SwappingHolder implements View.OnClickListener, View.OnLongClickListener {
SeekBar seekBar;
TextView timer, tv_time;
ImageView btn_play, iv_smile;
CardView cardView;
RelativeLayout parentView;
CustomizedAudioPlayer player;
MessageDetails messageDetails;
MediaPlayer mediaPlayer;
public AudioTypeViewHolder(View itemView) {
super(itemView, multiSelector);
this.timer = (TextView) itemView.findViewById(R.id.timer);
this.seekBar = (SeekBar) itemView.findViewById(R.id.audio_seekBar);
this.btn_play = (ImageView) itemView.findViewById(R.id.btnPlay);
this.tv_time = (TextView) itemView.findViewById(R.id.timeright);
this.cardView = (CardView) itemView.findViewById(R.id.card_view);
this.parentView = (RelativeLayout) itemView.findViewById(R.id.parent_view);
this.iv_smile =(ImageView) itemView.findViewById(R.id.smile1);
this.mediaPlayer = new MediaPlayer();
btn_play.setOnClickListener(this);
player = new CustomizedAudioPlayer(mediaPlayer, seekBar, btn_play, timer);
itemView.setOnLongClickListener(this);
itemView.setLongClickable(true);
btn_play.setOnLongClickListener(this);
btn_play.setLongClickable(true);
}
void initializeAudioPlayer(MessageDetails messageDetails) {
int colorId, gravity;
this.messageDetails = messageDetails;
if(messageDetails.getAudioPlayer() == null)
messageDetails.setAudioPlayer(player);
if (messageDetails.getSender().equals("to")) {
colorId = mContext.getResources().getColor(R.color.color_recevied_item);
gravity = Gravity.LEFT;
iv_smile.setVisibility(View.GONE);
} else {
colorId = mContext.getResources().getColor(R.color.color_sent_item);
gravity = Gravity.RIGHT;
iv_smile.setVisibility(View.VISIBLE);
iv_smile.setBackgroundResource(updateMessageStatus(messageDetails.getMstatus()));
}
player.initializePlayer(messageDetails.getMessage());
tv_time.setText(messageDetails.getTime());
cardView.setCardBackgroundColor(colorId);
parentView.setGravity(gravity);
}
@Override
public void onClick(View view) {
int id = view.getId();
if (id == R.id.btnPlay) {
if (!mediaPlayer.isPlaying()) {
// check my player is playing
//if not, stop if any other player is playing
for (MessageDetails messageDetails : messagesList) {
CustomizedAudioPlayer customPlayer = messageDetails.getAudioPlayer();
if(customPlayer != null)
customPlayer.stopTheMediaPlay();
}
//start my player
btn_play.setImageResource(R.drawable.img_pause);
player.startThePlayer();
notifyDataSetChanged();
} else {
btn_play.setImageResource(R.drawable.img_play);
player.stopTheMediaPlay();
}
}
}
@Override
public boolean onLongClick(View view) {
onItemLongPressed(this, messageDetails);
return true;
}
}
我的自定义音频播放器
public class CustomizedAudioPlayer implements SeekBar.OnSeekBarChangeListener,MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
private Handler myHandler = new Handler();
SeekBar seekbar;
MediaPlayer mediaPlayer;
boolean isPaused;
ImageView playBtn;
TextView timer;
StringBuilder mFormatBuilder;
Formatter mFormatter;
int totalDuration, currentDuration;
String path, chatId;
public CustomizedAudioPlayer(MediaPlayer mediaPlayer, SeekBar seekbar, ImageView view, TextView timer){
this.seekbar = seekbar;
this.playBtn = view;
this.timer = timer;
this.mediaPlayer = mediaPlayer;
mFormatBuilder = new StringBuilder();
mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
this.seekbar.setProgress(0);
this.seekbar.setMax(100);
this.seekbar.setOnSeekBarChangeListener(this);
}
public void initializePlayer(String filePath){
try{
if(path == null){
this.path = filePath;
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setDataSource(path);
mediaPlayer.prepare();
timer.setText(stringForTime( mediaPlayer.getDuration()));
}
}catch (Exception e){
}
}
public void startThePlayer(){
totalDuration = mediaPlayer.getDuration();
mediaPlayer.seekTo(currentDuration);
myHandler.postDelayed(updateProgress,100);
mediaPlayer.start();
}
public void stopTheMediaPlay(){
if(mediaPlayer.isPlaying()){
playBtn.setImageResource(R.drawable.img_play);
currentDuration = mediaPlayer.getCurrentPosition();
timer.setText(stringForTime( mediaPlayer.getDuration()));
myHandler.removeCallbacks(updateProgress);
mediaPlayer.pause();
}
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
playBtn.setImageResource(R.drawable.img_play);
seekbar.setProgress(0);
timer.setText(stringForTime( mediaPlayer.getDuration()));
myHandler.removeCallbacks(updateProgress);
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
myHandler.removeCallbacks(updateProgress);
playBtn.setImageResource(R.drawable.img_play);
mediaPlayer.pause();
isPaused = true;
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
currentDuration = progressToTimer(seekBar.getProgress(), totalDuration);
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
if(fromUser){
mediaPlayer.seekTo(currentDuration);
}
} else if (mediaPlayer == null) {
seekBar.setProgress(0);
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
currentDuration = progressToTimer(seekBar.getProgress(), totalDuration);
if (mediaPlayer.isPlaying() && mediaPlayer != null || (isPaused && mediaPlayer != null)) {
isPaused = false;
mediaPlayer.seekTo(currentDuration);
myHandler.postDelayed(updateProgress,100);
mediaPlayer.start();
playBtn.setImageResource(R.drawable.img_pause);
}
}
@Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
return false;
}
private Runnable updateProgress = new Runnable() {
public void run() {
totalDuration = mediaPlayer.getDuration();
currentDuration = mediaPlayer.getCurrentPosition();
int progress = getProgressPercentage();
float progressPer = ((float)progress/100);
float newPosition = (totalDuration) * progressPer;
seekbar.setProgress(progress);
timer.setText(stringForTime( (int) newPosition));
myHandler.postDelayed(this, 100);
}
};
private String stringForTime(int timeMs) {
int totalSeconds = timeMs / 1000;
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
mFormatBuilder.setLength(0);
if (hours > 0) {
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
} else {
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
}
}
public int getProgressPercentage(){
long currentSeconds = (currentDuration / 1000);
long totalSeconds = (totalDuration / 1000);
Double percentage =(((double)currentSeconds)/totalSeconds)*100;
return percentage.intValue();
}
public int progressToTimer(int progress, int totalDuration) {
totalDuration = (totalDuration / 1000);
int currentDuration = (int) ((((double)progress) / 100) * totalDuration);
// return current duration in milliseconds
return currentDuration * 1000;
}
}
我甚至尝试过放置
setIsRecyclable(假);
使用此项,项目的位置是稳定的,但播放音频文件时项目没有更新(即搜索栏,文件时间不更新)
您可以在以下屏幕截图中找到我的问题