滚动向上和向下列表视图时项目图像会发生变化

时间:2014-09-10 20:50:56

标签: android android-listview

我使用自定义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);
}

有人有任何想法吗?

2 个答案:

答案 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;
  }