我使用自定义Base Adapter for listview。每行包含进度条,图像按钮和2个textview。我已经为每一行创建了一个音频播放器,其中包含播放按钮(更改其图像以便在点击时暂停)和进度条(在按钮点击时开始显示进度)。当我滚动列表时出现问题:
1)当我向下滚动并返回时,图像按钮的图像返回播放,进度条会清除其进度,但歌曲仍在播放。
2)listview的其他项目开始在其图像按钮上显示暂停图像,进度条显示正在播放的歌曲的进度(我认为在每第6行之后,第7行就是这样)。 请帮我。这是我的自定义适配器:
public class AudioAdapter extends BaseAdapter {
Context context;
Uri[] URIs;
LayoutInflater layout;
ImageButton previousButton = null;
ProgressBar previousProgressBar = null;
static private Handler myHandler = new Handler();
public AudioAdapter(Context context, int resource, Uri[] URIs) {
// TODO Auto-generated constructor stub
this.context = context;
this.URIs = URIs;
}
class AudioViewHolder {
ImageButton play;
TextView date, duration;
ProgressBar progressBar;
public AudioViewHolder(View v) { // TODO Auto-generated constructor
// stub
play = (ImageButton) v.findViewById(R.id.imageButton_rowAudioplay);
date = (TextView) v.findViewById(R.id.textView_rowAudioDate);
duration = (TextView) v
.findViewById(R.id.textView_rowAudioDuration);
progressBar = (ProgressBar) v
.findViewById(R.id.progressBar_rowAudioplay);
}
}
@Override
public int getCount() { // TODO Auto-generated method stub
return URIs.length;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
final AudioViewHolder holder;
if (row == null) {
layout = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layout.inflate(R.layout.row_hometab_audio, parent, false);
row.setVisibility(View.INVISIBLE);
holder = new AudioViewHolder(row);
row.setTag(holder);
} else {
holder = (AudioViewHolder) row.getTag();
}
holder.duration.setText(AudioPlayer.getAudioMinutes(context,
URIs[position])
+ ":"
+ AudioPlayer.getAudioSeconds(context, URIs[position]));
DebugMessage.logMessage("Inside AudioAdapter getView() . isrowNULL = "
+ (row == null));
holder.progressBar.setTag(position);
holder.play.setTag(position);
holder.play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int row_position = (Integer) v.getTag();
if (holder.play == previousButton && AudioPlayer.isPlaying)
AudioPlayer.pauseAudio(holder);
else {
if (holder.play == previousButton
&& AudioPlayer.isPlaying == false) {
AudioPlayer.resumeAudio(holder);
AudioPlayer.ProgressBarUpdate(holder, myHandler);
} else if (AudioPlayer.isPlaying) {
AudioPlayer.StopAudio(previousButton,
previousProgressBar);
AudioPlayer.PlayAudio(context, URIs[row_position],
holder);
AudioPlayer.ProgressBarUpdate(holder, myHandler);
holder.play
.setImageResource(android.R.drawable.ic_media_pause);
previousButton = holder.play;
previousProgressBar = holder.progressBar;
AudioPlayer.isPlaying = true;
} else {
AudioPlayer.PlayAudio(context, URIs[row_position],
holder);
AudioPlayer.ProgressBarUpdate(holder, myHandler);
holder.play
.setImageResource(android.R.drawable.ic_media_pause);
previousButton = holder.play;
previousProgressBar = holder.progressBar;
AudioPlayer.isPlaying = true;
}
}
AudioPlayer.onAudioFinished(holder);
}
});
row.setVisibility(View.VISIBLE);
return row;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
这是我的播放器:
public class AudioPlayer {
static MediaPlayer mediaPlayer = null;
static String time;
public static boolean isPlaying = false;
static int currProgress;
public static void ProgressBarUpdate(
final AudioAdapter.AudioViewHolder holder, final Handler myHandler) {
myHandler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
currProgress = mediaPlayer.getCurrentPosition();
holder.progressBar.setProgress(currProgress);
myHandler.postDelayed(this, 100);
}
}, 100);
}
public static void PlayAudio(Context context, Uri filePath,
AudioAdapter.AudioViewHolder holder) {
mediaPlayer = MediaPlayer.create(context, filePath);
mediaPlayer.setLooping(false);
holder.progressBar.setVisibility(View.VISIBLE);
holder.progressBar.setMax(mediaPlayer.getDuration());
holder.play.setImageResource(android.R.drawable.ic_media_pause);
mediaPlayer.start();
}
public static void pauseAudio(AudioAdapter.AudioViewHolder holder) {
mediaPlayer.pause();
holder.progressBar.setVisibility(View.INVISIBLE);
holder.play.setImageResource(android.R.drawable.ic_media_play);
}
public static void StopAudio(ImageButton play,ProgressBar progressBar) {
mediaPlayer.stop();
mediaPlayer.release();
progressBar.setVisibility(View.INVISIBLE);
play.setImageResource(android.R.drawable.ic_media_play);
}
public static void resumeAudio(AudioAdapter.AudioViewHolder holder) {
// TODO Auto-generated method stub
mediaPlayer.start();
holder.progressBar.setVisibility(View.VISIBLE);
holder.progressBar.setMax(mediaPlayer.getDuration());
holder.play.setImageResource(android.R.drawable.ic_media_pause);
}
public static void onAudioFinished(final AudioAdapter.AudioViewHolder holder) {
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
DebugMessage.logMessage("Audio Completed");
holder.progressBar.setVisibility(View.INVISIBLE);
holder.play.setImageResource(android.R.drawable.ic_media_play);
}
});
}
public static String getAudioMinutes(Context context, Uri filePath) {
int duration = MediaPlayer.create(context, filePath).getDuration();
int min = (int) TimeUnit.MILLISECONDS.toMinutes((long) duration);
if (min < 10)
return String.valueOf("0" + min);
else
return String.valueOf(min);
}
public static String getAudioSeconds(Context context, Uri filePath) {
int duration = MediaPlayer.create(context, filePath).getDuration();
long sec = (long) (TimeUnit.MILLISECONDS.toSeconds((long) duration) - TimeUnit.MINUTES
.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) duration)));
if (sec < 10)
return String.valueOf("0" + sec);
else
return String.valueOf(sec);
}
有人有任何想法吗?
答案 0 :(得分:0)
click事件中的逻辑,它实际上更改了视图分配图像和可见性......每个getView()
调用都需要这样做。
所以我们假设您正在玩Song X
。如果该视图滚动离开屏幕,然后返回到屏幕上......它将关闭getView()
。 getView()
调用需要能够将View恢复为播放歌曲的状态。
所以理想情况下,对于每个getView()
,您需要一种方式来说,“嘿,我有这个URI。请告诉我它是否正在播放以及它是多少秒。”然后相应地更新您的观点。
答案 1 :(得分:0)
尝试将这些方法添加到适配器类:
@Override
public int getViewTypeCount() {
return getCount();
}
@Override
public int getItemViewType(int position) {
return position;
}