6

AndroidのdrawCircleやdrawPointなどのキャンバスの関数を使用しています。これはうまくいきます。

しかし、問題は、これらの異なるアイテムを遅延して描画することです。そのため、アニメーションのように見えます。

どのようなメカニズムを使用すればよいですか? 非同期で試しましたが、その方法は好きではありません。

間隔を空けて描くだけのタイマーを使用する必要がありますか、それとも他の賢い方法がありますか?

4

3 に答える 3

3

私はこの戦略を使用します。まず、そのように Handler と Runnable を宣言します。

    private final Observable mObservable = new Observable();
    private final static int TIME_STEP_MS = 5;
    private final Handler mHandler = new Handler();
    private final Runnable mTimeManager = new Runnable() 
    {
        public void run() 
        {
            mObservable.notifyObservers(TIME_STEP_MS);
            mHandler.postDelayed(mTimeManager, TIME_STEP_MS);
        }
    };

次に、タイム マネージャーを起動するときに mTimeManager.run() を呼び出すだけで、Observer(以前に追加した) s に定期的に通知を開始します。

何らかの理由でタイマーを停止する必要がある場合は、次のようにします。

    mHandler.removeCallbacks(mTimeManager);

[編集 - より完全なコード]

まず、そのようなカスタムの Observable オブジェクトを作成しました [これはオプションです]:

    private final Observable mObservable = new Observable()
    {
        public void notifyObservers()
        {
            setChanged();
            super.notifyObservers();
        };

        @Override
        public void notifyObservers(Object data) 
        {
            setChanged();
            super.notifyObservers(data);
        };
    };

その理由は、Observable クラスの外で setChanged() を呼び出すことができないからです。それは保護されており、変更されていない場合はオブザーバーに通知しません。

他の宣言は前に示したものと同じままです。今度はどこかでこれを開始する必要がありますTimeManager。私のアプリは LiveWallpaper であり、すべてのレンダリング要素を a を拡張するクラスにしますが、Thread必ずしも必要ではありません。これはfromクラスのmyのresumeDrawing()直後に呼び出され、メソッドは次のようになります。super.start();@Overridepublic synchronized void start()Thread

    public void resumeDrawing()
    {
        if (!mTimeManagerRunning) // just a boolean field in my class
        {
            System.err.println("Resuming renderer."); // just for debug
            mTimeManager.run();
            mTimeManagerRunning = true;
        }
        else
        {
            System.err.println("Renderer already running."); // just for debug
        }
    }

そしてそれは二重です:

    public void pauseDrawing()
    {
        if (mTimeManagerRunning)
        {
            System.err.println("Pausing renderer.");
            mHandler.removeCallbacks(mTimeManager);
            mTimeManagerRunning = false;
        }
        else
        {
            System.err.println("Renderer already paused.");
        }
    }

さて、これでタイム マネージャーを開始および停止できますが、誰が聞いているのでしょうか? 誰でもない!追加しましょう: Renderer のコンストラクターでObserver、オブジェクトにいくつかのを追加しmObservableます。そのうちの 1 つは Renderer 自体であるため、Renderer は拡張Threadおよび実装しObserverます。

    @Override // from Observer interface
    public void update(Observable arg0, Object arg1) 
    {
        mElapsedMsRedraw += (Integer) arg1; 

        if (mElapsedMsRedraw >= mDrawingMsPerFrame)
        {
            mElapsedMsRedraw = 0;
            drawEm(); // refresh the canvas and stuff
        }
    }

オブザーバーを追加するには、単に行うだけですmObservable.addObserver(THE_OBJECT - Implements Observer)

Canvas通知を受けるたびに自分のものを再レンダリングしないことがわかります。これは、描画したいオブジェクトの位置を内部的に更新するだけでなく、この TimeManager を他の考えに使用するためです。

したがって、描画を遅くするために必要なのは、時間の経過中にオブジェクトが内部的に変化する方法を変更することです。つまり、円や点などを意味します。または、時間ステップを変えることができます。最初のものをお勧めします。

それはより明確でしたか?お役に立てば幸いです。

于 2012-10-10T19:06:21.180 に答える
1

タイマーを使用するか、アニメーションを作成します。時間の経過とともに透明度が変化するなど、あらゆる種類のアニメーションを作成できます。

アニメーション リソースのAndroid ドキュメンテーションは次のとおりです。

于 2012-10-10T19:05:57.197 に答える