2017-11-18 1 views
0

RecyclerView을 사용하여 스트리밍 할 오디오 목록을 표시/재생하는 앱을 만들려고합니다. RecyclerView의 각 항목은 SeekBar, 단추 및 오디오 타이머의 경우 TextView입니다.RecyclerView의 마지막 항목에있는 SeekBar 만 작동합니다.

제가 직면 한 문제는 오디오를 재생할 때 seekbarRecyclerView의 마지막 항목에만 실행되고 있다는 것입니다. 나는 비슷한 다른 문제를 보았지만 내 문제를 해결할 수 없었다.

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

RunClickable 부분을 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

관련 문제