2012-10-10 5 views
6

私はアンドロイドにdrawCircleやdrawPointのようなキャンバスの関数を使用します。 これは正常に動作します。遅れてキャンバスに描く - "make onDraw()slow down"

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

どのようなメカニズムを使用しますか?非同期で試したことがありますが、私はそれをやり遂げるそのような方法はありません。

インターバルで描画するタイマーを使用するか、これを行うための他の巧妙な方法がありますか?

答えて

3

は、まず私がハンドラを宣言アニメーション資源Android DocumentationとRunnableのmTimeManager.run()を呼び出すと、私はObserver(以前に追加された)を定期的に通知し始めます。 [ - より完全なコードEDIT]

もOKですが、それをより明確にしましょうよりも、最初に私が作った

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); 
     }; 
    }; 

私はsetChanを呼び出すことができないからですObservableクラスの外側にあるged()は保護されています。変更されていなければ、オブザーバには通知されません。前に示したように

他の宣言は、今、私がどこかでこのTimeManagerを開始する必要があり、同じに保つ、私のアプリはライブ壁紙ですと私は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 
     } 
    } 

をし、それはデュアルだ:私はこの1つはThreadクラスからpublic synchronized void start()の私の@Overrideで右後super.start();と呼ばれ、この方法はresumeDrawing()と呼ばれる作られた、この方法は、そのように見える

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

これで、時間マネージャを開始して停止できますが、誰が聞いていますか?誰もいない!それでははadd'emてみましょう:オブザーバーにあなたを追加する

@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オブジェクト、それらの一つは、レンダラそのものなので、私のレンダラはThreadを拡張し、Observerを実装するためにいくつかのObserver秒を追加します単に行うmObservable.addObserver(THE_OBJECT - Implements Observer)

私はこのTimeManagerを使用するので

あなたは、私は私のもの、私が通知さてるたびに再レンダリングされないことを確認することができ、それは相手のちょうど私が欲しいのオブジェクトの位置を更新するようCanvasをリフレッシュよりも考えています内部的に描く

だから、描画を遅くする必要があるのは、時間が経過している間にオブジェクトが内部的に変化する方法を変更することです。あなたのサークルやポイントなどを意味します。

もっと明確でしたか?私はそれが助けて欲しい

+0

thxしかし、より完全な例を投稿できますか?実装を表示します。 – FooBar

+0

確かに、私は仕事中です。それは私が覚えているコードです。私は20分後に出発しますので、より完全なコードを提供します。 – HericDenis

+0

Ok @FooBar今私は家にいますあなたを助けます(: – HericDenis

1

私はタイマーを使うか、アニメーションを作成します。時間の経過とともに透明性を変えることを含むあらゆる種類のことを行うアニメーションを作成することができます。その後

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); 
     } 
    }; 

私は私の時間管理を開始したいとき、私はちょうど呼び出します。ここでは

はそのように私はこの戦略を使用し

0

私はこれを行うための洗練された方法があるかもしれないと考えていますが、私のニーズのために、私は多くの利点を持っている簡単な方法を使用:私は最初にすべてのポイントのために記録座標の(および必要に応じて他のデータ)を作成 をその場でポイントを描画するのではなく、描画してから、タイマ(Androidハンドラ、好ましくは)を使って再現してください。これはまた、実際の描画の間に多くの可能性を提供します:一時停止、早く/遅く、後ろに行く... この方法を複雑な図面に使用できるかどうかわかりませんが、図形、表面など

関連する問題