2

すべてが機能していますが、すべてのリスト ビューでシーク バーが更新されています が、オーディオは正しく再生されています

public class AudioPLayAdapter extends BaseAdapter implements
        OnCompletionListener, SeekBar.OnSeekBarChangeListener {
    private Activity activity;

    private ArrayList<String> al_fname = new ArrayList<String>();
    private static LayoutInflater inflater = null;
    private boolean flag_play;
    private MediaPlayer mPlayer = null;

    Handler seekHandler = new Handler();

    public AudioPLayAdapter(Activity a, ArrayList<String> al_fname) {
        activity = a;
        mPlayer = new MediaPlayer();
        this.al_fname = al_fname;
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }

    @Override
    public View getView(final int position, final View convertView,
            final ViewGroup parent) {
        View vi = convertView;

        if (convertView == null)
            vi = inflater.inflate(R.layout.audi_rec_lv_layout, null);

        final Button play_btn = (Button) vi.findViewById(R.id.play_stop_button);

        final SeekBar seekBar = (SeekBar) vi.findViewById(R.id.seekbar_play);

        play_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (!flag_play) {
                    play_btn.setText("Stop");
                    startPlaying();

                    flag_play = true;
                } else {
                    play_btn.setText("Play");
                    mPlayer.stop();
                    seekBar.setProgress(0);
                    flag_play = false;
                }

            }

            private void startPlaying() {
                // TODO Auto-generated method stub

                try {

                    mPlayer.reset();
                    FileInputStream rawFile = new FileInputStream(al_fname
                            .get(position));
                    Log.e("filename", al_fname.get(position));
                    mPlayer.setDataSource(rawFile.getFD());
                    // mPlayer.setDataSource(mFileName);
                    mPlayer.prepare();
                    mPlayer.start();
                    // set Progress bar values

                    seekBar.setProgress(0);
                    seekBar.setMax(100);

                    // seekHandler.postDelayed(updateSeek, 100);
                    // Updating progress bar

                    updateProgressBar();

                } catch (IOException e) {
                    Log.e("preparefailed", "prepare() failed");
                }

            }

            private void updateProgressBar() {
                // TODO Auto-generated method stub

                seekHandler.postDelayed(mUpdateTimeTask, 100);
            }

            private Runnable mUpdateTimeTask = new Runnable() {
                public void run() {
                    long totalDuration = mPlayer.getDuration();
                    long currentDuration = mPlayer.getCurrentPosition();
                    String str1 = new String();
                    // holder.timer_tv.setText(str1.valueOf(currentDuration));
                    // Updating progress bar
                    int progress = (int) (getProgressPercentage(
                            currentDuration, totalDuration));
                    // Log.d("Progress", ""+progress);
                    // if(position==holder.seekBar.getId())
                    // seekBar.setTag(position);
                    seekBar.setProgress(progress);

                    // Running this thread after 100 milliseconds
                    seekHandler.postDelayed(this, 100);
                    if (!mPlayer.isPlaying()) {
                        play_btn.setText("Play");

                        flag_play = false;
                    }
                    if (!flag_play)
                        seekBar.setProgress(0);

                }

                private int getProgressPercentage(long currentDuration,
                        long totalDuration) {
                    // TODO Auto-generated method stub
                    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();
                }
            };

        });
        return vi;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return al_fname.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        // TODO Auto-generated method stub

    }

}
4

1 に答える 1

4

が呼び出されるたびgetViewに、新しいが作成され、その行ビューのOnClickListenerとして追加されます。play_btn

これらの匿名OnClickListenerのそれぞれにはフィールドがありますRunnable mUpdateTimeTask。このランナブルはハンドラーに投稿され、その後何度も自分自身を投稿し続けます。

新しい行の再生が開始されると、2 つRunnableの が投稿され、異なるシークバーを更新する可能性があります。クリックして再生するたびに、新しいランナブルが追加されます。

あなたが望むのは、どのアイテムが再生されているかを追跡し、不要になったときにランナブルの投稿を停止することです。多くても、一度に 1 つのランナブルを持つ必要があります。シークバーを定期的に更新するより良い方法を探すこともできます (存在する場合)。

getViewビューがリサイクルされた場合 (つまり、パラメーターから取得convertViewされた場合)、ビューが現在別の に使用されているかどうかを確認する必要があります。position別の位置にある場合は、この行の の更新を停止しseekbarます。

したがって、次のようなものが必要になります (曲の終了時の処理や、再生を停止する方法など、いくつかの詳細がまだ不足しており、演習として残しています): ( https://github.com/curobosqui/PlaybackInListの完全なデモ プロジェクト/ツリー/StackoverflowAnswer )

public class ListWithSongsActivity extends ListActivity {
    private static final int NOT_PLAYING = -1;

    private static final String TAG = "SongList";

    List<String> mSongs = new ArrayList<String>(50);
    private ArrayAdapter<String> mAdapter = null;
    private final MediaPlayer mPlayer = new MediaPlayer();
    private int mPlayingPosition = NOT_PLAYING;
    private Handler mHandler = new Handler();

    private PlaybackUpdater mProgressUpdater = new PlaybackUpdater();

    public ListWithSongsActivity() {
        //add list of songs in your device for sample
        mSongs.addAll(Arrays.asList(new String[]{
            "/sdcard/Download/B00G2ID7FE_(disc_1)_01_-_Play_Me_(Version).mp3",
            "/sdcard/Download/The Slip/10 Demon Seed.mp3"
        }));
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_list_with_songs);
        mAdapter = new ArrayAdapter<String>(this, R.layout.list_item, android.R.id.text1, mSongs) {

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v = super.getView(position, convertView, parent);
                ProgressBar pb = (ProgressBar) v.findViewById(R.id.progressBar1);   //Cast
                if (position == mPlayingPosition) {
                    //pb.setVisibility(View.VISIBLE);
                    mProgressUpdater.mBarToUpdate = pb;
                    mHandler.postDelayed(mProgressUpdater, 100);
                } else {
                    //pb.setVisibility(View.GONE);
                    pb.setProgress(0);
                    if (mProgressUpdater.mBarToUpdate == pb) {
                        //this progress would be updated, but this is the wrong position
                        mProgressUpdater.mBarToUpdate = null;
                    }
                }
                return v;
            }
        };
        setListAdapter(mAdapter);
    }

    private void stopPlayback()
    {
        mPlayingPosition = NOT_PLAYING;
        mProgressUpdater.mBarToUpdate = null;
        mPlayer.stop();
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        //start playing item at position
        try {
            mPlayer.reset();
            mPlayer.setDataSource(mSongs.get(position));
            mPlayer.prepare();
            mPlayer.start();
            mPlayingPosition = position;

            mHandler.postDelayed(mProgressUpdater, 500);

            //trigger list refresh, this will make progressbar start updating if visible
            mAdapter.notifyDataSetChanged();
        } catch (IOException e) {
            Log.e(TAG, "unable to play: " + mSongs.get(position));
            e.printStackTrace();
            stopPlayback();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.list_with_songs, menu);
        return true;
    }

    @Override
    protected void onStop() {
        super.onStop();
        mPlayer.stop();
    }

    private class PlaybackUpdater implements Runnable {
        public ProgressBar mBarToUpdate = null;

        @Override
        public void run() {
            if ((mPlayingPosition != NOT_PLAYING) && (null != mBarToUpdate)) {
                mBarToUpdate.setProgress( (100*mPlayer.getCurrentPosition() / mPlayer.getDuration()) );    //Cast
                mHandler.postDelayed(this, 500);
            } else {
                //not playing so stop updating
            }
        }
    }
}

そして、単純な行レイアウトを使用しますlist_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
于 2014-03-06T06:53:46.103 に答える