2017-11-18 61 views
0

我正在尝试创建一个应用程序,我正在使用RecyclerView来显示/播放要流式传输的音频列表。 RecyclerView中的每个项目都有一个SeekBar,一个按钮和一个TextView音频计时器。只有RecyclerView的最后一项中的SeekBar正在工作

我面临的问题是,当我播放音频时,seekbar仅在RecyclerView的最后一项中运行。我见过类似的其他问题,但一直未能解决我的问题。下面是我使用的适配器代码:

public class AudioAdapter extends RecyclerView.Adapter<AudioAdapter.ViewHolder> { 
Context context; 
LayoutInflater inflator; 
ArrayList<AudioModel> list = new ArrayList(); 
SeekBar mSeekBar; 
TextView mTvAudioLength; 
MediaPlayer mMediaPlayer; 

public AudioAdapter(Context context, ArrayList<AudioModel> list) { 
    this.context = context; 
    this.list = list; 
    inflator = LayoutInflater.from(context); 
} 

@Override 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = inflator.inflate(R.layout.audio_recyclerview_layout, parent, false); 
    AudioAdapter.ViewHolder viewHolder = new AudioAdapter.ViewHolder(view); 
    return viewHolder; 
} 

@Override 
public void onBindViewHolder(final ViewHolder holder, final int position) { 

    final AudioModel modelList = list.get(position); 
    //holder.tvAudioLength.setText(modelList.duration); 
    holder.tvAudioName.setText(modelList.name); 

    // Initializing MediaPlayer 
    final MediaPlayer mediaPlayer = new MediaPlayer(); 

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    try { 
     mediaPlayer.setDataSource(modelList.url); 
     mediaPlayer.prepare();// might take long for buffering. 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    mMediaPlayer = mediaPlayer; 
    mTvAudioLength = holder.tvAudioLength; 
    mSeekBar = holder.seekBar; 
    holder.seekBar.setMax(mediaPlayer.getDuration()); 
    run.run(); 
    holder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
     @Override 
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
      if (mediaPlayer != null && fromUser) { 
       mediaPlayer.seekTo(progress); 
      } 
     } 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 

     } 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 

     } 
    }); 
    holder.tvAudioLength.setText(calculateDuration(mediaPlayer.getDuration())); 
    holder.btn_play.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      if (!mediaPlayer.isPlaying()) { 
       mediaPlayer.start(); 
       holder.btn_play.setText("Pause"); 
      } else { 
       mediaPlayer.pause(); 
       holder.btn_play.setText("Play"); 
      } 
     } 
    }); 
} 
Runnable run = new Runnable() { 
    @Override 
    public void run() { 
     // Updateing SeekBar every 100 miliseconds 
     Handler seekHandler = new Handler(); 
     mSeekBar.setProgress(mMediaPlayer.getCurrentPosition()); 
     seekHandler.postDelayed(run, 100); 
     //For Showing time of audio(inside runnable) 
     int miliSeconds = mMediaPlayer.getCurrentPosition(); 
     if(miliSeconds!=0) { 
      //if audio is playing, showing current time; 
      long minutes = TimeUnit.MILLISECONDS.toMinutes(miliSeconds); 
      long seconds = TimeUnit.MILLISECONDS.toSeconds(miliSeconds); 
      if (minutes == 0) { 
       mTvAudioLength.setText("0:" + seconds); 
      } else { 
       if (seconds >= 60) { 
        long sec = seconds - (minutes * 60); 
        mTvAudioLength.setText(minutes + ":" + sec); 
       } 
      } 
     }else{ 
      //Displaying total time if audio not playing 
      int totalTime=mMediaPlayer.getDuration(); 
      long minutes = TimeUnit.MILLISECONDS.toMinutes(totalTime); 
      long seconds = TimeUnit.MILLISECONDS.toSeconds(totalTime); 
      if (minutes == 0) { 
       mTvAudioLength.setText("0:" + seconds); 
      } else { 
       if (seconds >= 60) { 
        long sec = seconds - (minutes * 60); 
        mTvAudioLength.setText(minutes + ":" + sec); 
       } 
      } 
     } 
    } 

}; 

@Override 
public int getItemCount() { 
    return list.size(); 
} 

class ViewHolder extends RecyclerView.ViewHolder { 
    Button btn_play; 
    TextView tvAudioLength; 
    TextView tvAudioName; 
    SeekBar seekBar; 

    public ViewHolder(View itemView) { 
     super(itemView); 
     // mTvAudioLength =(TextView) itemView.findViewById(R.id.tv_audio_lenght); 
     // mSeekBar = (SeekBar) itemView.findViewById(R.id.seekBar); 
     btn_play = (Button) itemView.findViewById(R.id.btn_play); 
     tvAudioLength = (TextView) itemView.findViewById(R.id.tv_audio_lenght); 
     tvAudioName = (TextView) itemView.findViewById(R.id.tv_audio_name); 
     seekBar = (SeekBar) itemView.findViewById(R.id.seekBar); 
     //seekBar.setTag(itemView.findViewById(R.id.seekBar)); 
    } 
} 

private String calculateDuration(int duration) { 
    String finalDuration = ""; 
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration); 
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration); 
    if (minutes == 0) { 
     finalDuration = "0:" + seconds; 
    } else { 
     if (seconds >= 60) { 
      long sec = seconds - (minutes * 60); 
      finalDuration = minutes + ":" + sec; 
     } 
    } 
    return finalDuration; 
} 

}您已经创建了一个可运行的布局

image

回答

0

我将Runnable部分复制到OnClickListener中,并解决了问题。 更新的代码:

public class AudioAdapter extends RecyclerView.Adapter<AudioAdapter.ViewHolder> { 
Context context; 
LayoutInflater inflator; 
ArrayList<AudioModel> list = new ArrayList(); 
Handler seekHandler = new Handler(); 
Runnable run; 

public AudioAdapter(Context context, ArrayList<AudioModel> list) { 
    this.context = context; 
    this.list = list; 
    inflator = LayoutInflater.from(context); 
} 

@Override 
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view = inflator.inflate(R.layout.audio_recyclerview_layout, parent, false); 
    AudioAdapter.ViewHolder viewHolder = new AudioAdapter.ViewHolder(view); 
    return viewHolder; 
} 

@Override 
public void onBindViewHolder(final ViewHolder holder, final int position) { 

    final AudioModel modelList = list.get(position); 
    holder.tvAudioName.setText(modelList.name); 

    // Initializing MediaPlayer 
    final MediaPlayer mediaPlayer = new MediaPlayer(); 

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    try { 
     mediaPlayer.setDataSource(modelList.url); 
     mediaPlayer.prepare();// might take long for buffering. 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    holder.seekBar.setMax(mediaPlayer.getDuration()); 
    holder.seekBar.setTag(position); 
    //run.run(); 
    holder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
     @Override 
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
      if (mediaPlayer != null && fromUser) { 
       mediaPlayer.seekTo(progress); 
      } 
     } 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 

     } 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 

     } 
    }); 
    holder.tvAudioLength.setText("0:00/"+calculateDuration(mediaPlayer.getDuration())); 
    holder.btn_play.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      if (!mediaPlayer.isPlaying()) { 
       mediaPlayer.start(); 
       holder.btn_play.setText("Pause"); 
       run = new Runnable() { 
        @Override 
        public void run() { 
         // Updateing SeekBar every 100 miliseconds 
         holder.seekBar.setProgress(mediaPlayer.getCurrentPosition()); 
         seekHandler.postDelayed(run, 100); 
         //For Showing time of audio(inside runnable) 
         int miliSeconds = mediaPlayer.getCurrentPosition(); 
         if(miliSeconds!=0) { 
          //if audio is playing, showing current time; 
          long minutes = TimeUnit.MILLISECONDS.toMinutes(miliSeconds); 
          long seconds = TimeUnit.MILLISECONDS.toSeconds(miliSeconds); 
          if (minutes == 0) { 
           holder.tvAudioLength.setText("0:" + seconds + "/" +calculateDuration(mediaPlayer.getDuration())); 
          } else { 
           if (seconds >= 60) { 
            long sec = seconds - (minutes * 60); 
            holder.tvAudioLength.setText(minutes + ":" + sec+ "/" +calculateDuration(mediaPlayer.getDuration())); 
           } 
          } 
         }else{ 
          //Displaying total time if audio not playing 
          int totalTime=mediaPlayer.getDuration(); 
          long minutes = TimeUnit.MILLISECONDS.toMinutes(totalTime); 
          long seconds = TimeUnit.MILLISECONDS.toSeconds(totalTime); 
          if (minutes == 0) { 
           holder.tvAudioLength.setText("0:" + seconds); 
          } else { 
           if (seconds >= 60) { 
            long sec = seconds - (minutes * 60); 
            holder.tvAudioLength.setText(minutes + ":" + sec); 
           } 
          } 
         } 
        } 

       }; 
       run.run(); 
      } else { 
       mediaPlayer.pause(); 
       holder.btn_play.setText("Play"); 
      } 
     } 
    }); 
} 

@Override 
public int getItemCount() { 
    return list.size(); 
} 

class ViewHolder extends RecyclerView.ViewHolder { 
    Button btn_play; 
    TextView tvAudioLength; 
    TextView tvAudioName; 
    SeekBar seekBar; 

    public ViewHolder(View itemView) { 
     super(itemView); 
     // mTvAudioLength =(TextView) itemView.findViewById(R.id.tv_audio_lenght); 
     // mSeekBar = (SeekBar) itemView.findViewById(R.id.seekBar); 
     btn_play = (Button) itemView.findViewById(R.id.btn_play); 
     tvAudioLength = (TextView) itemView.findViewById(R.id.tv_audio_lenght); 
     tvAudioName = (TextView) itemView.findViewById(R.id.tv_audio_name); 
     seekBar = (SeekBar) itemView.findViewById(R.id.seekBar); 

    } 
} 

private String calculateDuration(int duration) { 
    String finalDuration = ""; 
    long minutes = TimeUnit.MILLISECONDS.toMinutes(duration); 
    long seconds = TimeUnit.MILLISECONDS.toSeconds(duration); 
    if (minutes == 0) { 
     finalDuration = "0:" + seconds; 
    } else { 
     if (seconds >= 60) { 
      long sec = seconds - (minutes * 60); 
      finalDuration = minutes + ":" + sec; 
     } 
    } 
    return finalDuration; 
} 

}

0

图像。所以创建一个新的线程来更新你的seekbar。在该线程中,您使用mSeekBar.setProgress(mMediaPlayer.getCurrentPosition());更新与邮件线程不同步的进度。在执行每个项目视图时,会创建一个单独的线程,并且mSeekbar实例不会保留正确的实例(即)创建新视图时创建一个新线程,并通过mSeekbar获取新实例。最后,分配给mSeekbar的seekbar的最后一个实例。所以更新只发生在最后一个搜索栏中。为什么你为进度条更新创建另一个可运行的?

+0

另一个可运行?我不明白。我必须做些什么来解决这个问题? – AD1TYA

+0

'Runnable run = new Runnable()'我在说这条线 –

+0

那么,我有什么需要改变它的工作? – AD1TYA

相关问题