私はListView
に音声メッセージを表示します(WhatsAppのように)、私はBaseAdapter
を使用しています。私のレイアウトにはとSeekBar
が含まれています。 私がしたいのは、再生button
のクリックでオーディオを再生し、SeekBar
を更新することです。リストビューのMediaPlayerに関連付けられた複数のシークバー
私はそれを更新するこのカスタムSeekBar
を実装しました。
SelfUpdatingSeekBar.java
:私はItem1
をクリックしたときに問題がある
public View getView(final int i, View convertView, ViewGroup viewGroup){
final ViewHolder viewHolder;
if(convertView == null){
LayoutInflater inflater = ((MainActivity) context).getLayoutInflater();
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.sent_voice_bubble, viewGroup, false);
viewHolder.sent_voice_seekbar = (SelfUpdatingSeekBar) convertView.findViewById(R.id.sent_seekbar);
viewHolder.sent_voice_seekbar.setMediaPlayer(mMediaPlayer);
viewHolder.sent_voice_play = (ImageView) convertView.findViewById(R.id.sent_playAudio);
viewHolder.sent_voice_container = convertView.findViewById(R.id.sent_vmessagesection);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(((int)(x * 0.7f)), RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
viewHolder.sent_voice_container.setLayoutParams(params);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.sent_voice_play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Check if the Item is currently playing
if(list.get(i).isPlaying()){
// Stop audio and save progress
stopItemAudio(list.get(i), viewHolder.sent_voice_seekbar);
// Change button's image to Pause ||
((ImageView) v).setImageDrawable(((MainActivity) context).pauseDrawable);
}else{
// Start audio and update the SeekBar
playItemAudio(list.get(i), viewHolder.sent_voice_seekbar);
// Change button's image to Play >
((ImageView) v).setImageDrawable(((MainActivity) context).playDrawable);
}
}
});
if(list.get(i).isPlaying()){
viewHolder.sent_voice_seekbar.setActive(list.get(i).seekbar_resume_position);
viewHolder.sent_voice_play.setImageDrawable(((MainActivity) context).pauseDrawable);
}else{
viewHolder.sent_voice_seekbar.setInactive(list.get(i).seekbar_resume_position);
viewHolder.sent_voice_play.setImageDrawable(((MainActivity) context).playDrawable);
}
return convertView;
}
public void stopItemAudio(AudioRow item, SelfUpdatingSeekBar seekBar){
if(mMediaPlayer == null){
mMediaPlayer = new MediaPlayer();
}
mMediaPlayer.stop();
item.setPlaying(false);
int percentage = getProgressPercentage(mMediaPlayer.getCurrentPosition(), mMediaPlayer.getDuration());
item.setSeekBarResumePosition(percentage);
item.setMediaPlayerResumePosition(mMediaPlayer.getCurrentPosition());
seekBar.setInactive(percentage);
notifyDataSetChanged();
}
public void playItemAudio(final AudioRow item, SelfUpdatingSeekBar seekBar){
if(mMediaPlayer == null){
mMediaPlayer = new MediaPlayer();
}
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(item.audioPath);
mMediaPlayer.prepare();
mMediaPlayer.seekTo(item.mediaPlayer_resume_position);
seekBar.setActive(item.seekbar_resume_position); // Starts from where it stopped
mMediaPlayer.start();
// declaring Item started to play
item.setPlaying(true);
notifyDataSetChanged();
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
item.setSeekBarResumePosition(0);
item.setPlaying(false);
}
});
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public int getProgressPercentage(long currentDuration, long totalDuration){
Double percentage = (double) 0;
long currentSeconds = (int) (currentDuration/1000);
long totalSeconds = (int) (totalDuration/1000);
// calculating percentage
percentage =(((double)currentSeconds)/totalSeconds)*100;
// return percentage
return percentage.intValue();
}
}
、それが再生を開始し、両方SeekBarsがでアニメーション化Item2
をクリックしてください:
public class SelfUpdatingSeekBar extends SeekBar {
MediaPlayer mp;
boolean mActive;
public void setMediaPlayer(MediaPlayer mp){
this.mp = mp;
}
Runnable mUpdate = new Runnable() {
@Override
public void run() {
long totalDuration = mp.getDuration();
long currentDuration = mp.getCurrentPosition();
// Updating progress bar
int progress = (int)(getProgressPercentage(currentDuration, totalDuration));
setProgress(progress);
postDelayed(this, 100);
}
} ;
public void setActive(int progress) {
if (!mActive) {
mActive = true;
removeCallbacks(mUpdate);
setProgress(progress);
post(mUpdate);
}
}
public void setInactive(int progress) {
if (mActive) {
mActive = false;
removeCallbacks(mUpdate);
}
setProgress(progress);
}
public SelfUpdatingSeekBar(Context context) {
super(context);
}
public SelfUpdatingSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SelfUpdatingSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SelfUpdatingSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public int getProgressPercentage(long currentDuration, long totalDuration){
Double percentage = (double) 0;
long currentSeconds = (int) (currentDuration/1000);
long totalSeconds = (int) (totalDuration/1000);
// calculating percentage
percentage =(((double)currentSeconds)/totalSeconds)*100;
// return percentage
return percentage.intValue();
}
}
これは私のgetView()
がどのように見えるかです同じ時間、それは私が停止しなかったので期待されていますのクリックでItem2
私の質問は:
Item2
のクリックで以前の演奏Item1
を停止する適切な方法は何ですか?
ありがとうございました! MainActivityにあるアップデート実行可能ファイルについて、それはそういう意味だったが、私はここでこの答えを見た。もっと信頼できると思った。http://stackoverflow.com/questions/33807340/listview-recycling-switches-seekbar-position – user3463199
このアプローチの問題点は、新しいオーディオを再生したいときに、あなたがそのアップデートを止めることができるようにする前に、どのSeekBarが再生されているのか把握する必要があるということです。その答えは、グローバルな静的変数を使ってその問題を解決します。アクティビティ内に単一のRunnableと単一のMediaPlayerを持つことは別の解決策です。私は、あなたが 'onStop()'や 'onStart()'のようなアクティビティライフサイクルのコールバックを簡単にやり直すことができます。 – gesuwall