2016-04-07 15 views
1

私は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を停止する適切な方法は何ですか?

答えて

1

お客様のSeekBar実装には、独自のMediaPlayerはありません。アクティビティにはMediaPlayerインスタンスが1つだけあります。 iMainActivityそのSeekBarの現在再生中の項目と同じではありません。最初の引数があれば、あなたのgetView()実装に今

MediaPlayer mMediaPlayer = ((MainActivity) context).getSingleMediaPlayer(); 
((MainActivity) context).setCurrentlyPlayingItem(i); 
mMediaPlayer.reset(); 
mMediaPlayer.setDataSource(item.audioPath); 
mMediaPlayer.prepare(); 
notifyDatasetHasChanged() 

:「再生」ボタンがあなたのリストビューにクリックされるたびに、あなたはこのような何かを0にする必要があります。

MainActivityも、アップデート実行可能ファイルを実装するものである必要があります。この時点では、通常のSeekBarだけを使用することをお勧めします。

public View getVisibleItemView(int position){ 
     if(listview.getCount() > 0) { 
      int start = listview.getFirstVisiblePosition(); 
      for (int i = start, j = listview.getLastVisiblePosition(); i <= j; i++) { 
       if (i == position) { 
        return listview.getChildAt(i - start); 
       } 
      } 
     } 
     return null; 
    } 

この関数は、との見解を返します正しい表示を更新するには、あなたはあなたのMainActivityでこの機能を必要とするので、ユーザは、異なる位置にスクロールしている可能性があるため、それは、表示されている場合は最初に把握する必要がありSeekBarを更新したい場合にのみ表示し、そうでない場合はnullを返します。更新ランナブルで呼び出す必要があります。結果がnullでない場合は、SeekBarを更新します。

さらに、アダプター内のコンテキスト参照をキャストする代わりに、MainActivityにインターフェイスを使用することを検討してください。

+0

ありがとうございました! MainActivityにあるアップデート実行可能ファイルについて、それはそういう意味だったが、私はここでこの答えを見た。もっと信頼できると思った。http://stackoverflow.com/questions/33807340/listview-recycling-switches-seekbar-position – user3463199

+0

このアプローチの問題点は、新しいオーディオを再生したいときに、あなたがそのアップデートを止めることができるようにする前に、どのSeekBarが再生されているのか把握する必要があるということです。その答えは、グローバルな静的変数を使ってその問題を解決します。アクティビティ内に単一のRunnableと単一のMediaPlayerを持つことは別の解決策です。私は、あなたが 'onStop()'や 'onStart()'のようなアクティビティライフサイクルのコールバックを簡単にやり直すことができます。 – gesuwall

関連する問題