0

サウンドファイルの読み込みと再生を試す簡単なアプリを作成しようとしています。2 つのサウンドがあり、それらのリストを取得して、クリックされた方を再生したいと考えています。次のコードが機能します。

public class SoundPoolTest extends ListActivity {
    String sounds[] = { "shot", "explode" };
    SoundPool soundPool;
    int[] soundId = new int[sounds.length];
    {
        for (int i = 0; i < soundId.length; i++) {
            soundId[i] = -1;
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);

        super.onCreate(savedInstanceState);
        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, sounds));
        for (int i = 0; i < sounds.length; i++) {

            try {
                AssetManager assetManager = getAssets();
                AssetFileDescriptor descriptor = assetManager.openFd("sound/"
                        + sounds[i] + ".wav");
                soundId[i] = soundPool.load(descriptor, 1);
            } catch (IOException e) {
                TextView textView = (TextView) super.getListView()
                        .getChildAt(i);
                textView.setText("Could not load file!");
            }
        }
    }

    protected void onListItemClick(ListView list, View view, int position,
            long id) {
        super.onListItemClick(list, view, position, id);
        if (soundId[position] != -1) {
            soundPool.play(soundId[position], 1, 1, 0, 0, 1);
        }
    }
}

ただし、引数を台無しにしてassetManager.openFd、例外ハンドラーをテストするファイルが見つからないようにすると、リストをレンダリングする前にアプリケーション強制が終了します (LogCat 出力thread exiting with uncaught exception)。問題はtextView.setText("Could not load file!");行です。コメントアウトしても問題ありません。さらに不可解なのは、catch空のままにして同じコードをonListItemClickメソッドに入れると、次のようになることです。

protected void onListItemClick(ListView list, View view, int position,
            long id) {
        super.onListItemClick(list, view, position, id);
        TextView textView = (TextView) super.getListView().getChildAt(position);
        textView.setText("Clicked!");
        if (soundId[position] != -1) {
            soundPool.play(soundId[position], 1, 1, 0, 0, 1);
        }
    }

意図したとおりにクリックするとテキストが変更され、問題なく実行されます。この振る舞いが理解できません。

4

2 に答える 2

0

for()ループでこの変更を行ってから、試してください。

for (int i = 0; i < sounds.length; i++) {

        try {
            AssetManager assetManager = getAssets();
            AssetFileDescriptor descriptor = assetManager.openFd("sound/"
                    + sounds[i] + ".wav");
            TextView textView = (TextView) super.getListView()
                    .getChildAt(i);
            soundId[i] = soundPool.load(descriptor, 1);
        } catch (IOException e) {
            textView.setText("Could not load file!");
        }
    }
于 2012-12-03T09:13:11.673 に答える
0

問題はおそらくsuper.getListView().getChildAt(i);ListView作成されたすべての子ビューを維持していないことです。画面に表示されているビューへの参照のみを保持します。画面から消えたビューはリサイクルされ、他のコンテンツに再利用されます。これにより、基になるデータが大きい場合に何百ものビューを管理する必要がなくなります。

getView()代わりに、アダプタのメソッドからサウンドをロードしてみてください。ListView一般的に、外部からアイテムを手に入れようとしないでくださいgetView()

于 2012-12-03T04:32:22.060 に答える