0

ユーザーの描画を含むビューがあります。「再生」ボタンをクリックすると、最初から最後まで画像を描画するループが必要です。

これを実行しようとすると、基本的に再生ボタンの onClickListener 内にループがあり、ビューを無効にし、待機し、次のポイントのセットを設定し、再び無効にします。

問題は、画像全体が描画されるまで画像が実際に再描画されないことです。つまり、本質的に何も起こらず、突然すべてが終了します。いくつかの調査を行った後、invalidate はメインの UI スレッドに時間があるときに再描画するように指示していると思いますが、リスナーの処理に既にハングアップしているため、ループが終了するまで実際には描画されません。postInvalidate を使用して onDraw を直接呼び出してみましたが、他に考えられるばかげたことはほとんどありませんが、これを機能させる方法がわかりません。

以下にいくつかのコード スニペットを示します。

私のPaintActivity(PaintAreaViewがある)では、スクラバーは描画の進行状況を示します。onProgressChanged の最初の行は、シーク バーを手動で使用すると機能しますが、再生を押すと機能しません。そのため、すべてのエクストラを追加しようとしました。

        _scrubber.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            _paintAreaView.setPointsToDraw(_scrubber.getProgress());
            _paintAreaView.invalidate();
            _mainViewGroup.invalidate();
            _paintAreaView.postInvalidate();
            _mainViewGroup.postInvalidate();
            _paintAreaView.drawPoints(_paintAreaView.getCanvas());
            _paintAreaView.invalidate();
        }...

私の再生ボタンのもの:

        play.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ...
            playDrawing();
            ...
        }
    });

    private void playDrawing()
{
    int endPoint = getPaintPointCount();

    while(_scrubber.getProgress() < endPoint)
    {
        _scrubber.incrementProgressBy(1);

        try{
            Thread.sleep(10);
        }catch(InterruptedException e)
        {
            Thread.currentThread().interrupt();
        }
        //_paintAreaView.setPointsToDraw(_scrubber.getProgress());
        //_paintAreaView.invalidate();
        //_mainViewGroup.invalidate();
        if(_isPaused)
            break;
    }
}

私はその睡眠を使用することの大ファンではありませんが、他の解決策に苦労しており、それが私の次の調査対象です. しかし、この質問では、進行状況バーをインクリメントすると onProgressChanged が正常に呼び出されますが、再生ボタンのクリック リスナーから出るまではビューが描画されません。

これを機能させるためにリスナーから出るまで待たなければならない場合、私は十分に慣れていないので、どのようにアプローチすればよいかわかりません。

私の悪いコードで申し訳ありませんが、ここで何が起こっているのか、これを機能させるために何を理解する必要があるのか​​ を理解するのに役立つ助けをいただければ幸いです。

ありがとうございました!

4

1 に答える 1

0

私が行ったすべてが必要かどうかはわかりませんが、問題であるメイン UI スレッドの理論に基づいて行った変更を次に示します。

クラス Thread メンバー変数を作成しました。

private Thread _drawThread;

onCreate() で:

_drawThread = new Thread(){
    public void run(){
        playDrawing();
    }
};

再生ボタン onClick:

play.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         ...
         _drawThread.start();
    }
});

私がやりたいことをやっているようです!2回目に再生を押したときにアプリがクラッシュすることを除いて:)ここから、その問題を理解するのは悪くないと思います。

EDIT----- メンバー変数にする代わりに、再生ボタン onClickListener でスレッドを作成すると、クラッシュが修正されました。メイン スレッドでリスナーが範囲外になるとすぐにスレッドが破棄されると誤って想定していましたが、そうではないと思います。

于 2013-10-23T00:16:54.937 に答える