2012-10-10 22 views
6

我在android中使用drawCircle和drawPoint之類的畫布函數。 這工作正常。延遲在畫布上繪製 - 「make onDraw()減慢」

但現在的問題是延遲繪製這些不同的項目,所以它看起來像一個動畫。

我應該使用什麼樣的機制?嘗試過異步,但我不喜歡這樣做。

我應該使用某種類型的計時器,它只是間隔繪製或有其他聰明的方法來做到這一點?

回答

3

我使用這個策略,首先我宣佈一個處理器和一個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(之前添加)。

如果你需要某種原因停止計時器或東西,你只是這樣做:

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 ged()在Observable類之外 - 它是受保護的,如果它沒有改變,它不會通知任何觀察者。

的其他聲明保持和以前一樣所示,現在我需要從某個地方開始這個TimeManager,我的應用程序是一個LiveWallpaper,我讓所有的東西渲染成延伸Thread一類,但你並不需要是必然,我做了一個方法叫做resumeDrawing(),這個人是我的public synchronized void start()@OverrideThread類調​​用之後super.start();,該方法看起來像這樣:

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

好吧,現在我們可以啓動和停止時間管理器,但是誰在監聽?沒有人!讓我們add'em:在我的渲染器的構造我添加一些Observer s到我mObservable對象,其中的一個是渲染器本身,所以我的渲染器擴展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)

你可以看到,我不每次我通知時重新渲染我的東西,那是因爲我使用這個TimeManager其他認爲不僅僅是刷新Canvas如更新我想要的對象的位置在內部繪製。所以,你需要減慢繪圖的速度是改變你的對象內部在時間流逝的過程中改變的方式,我的意思是你的圈子和點等等,或者你可以有時間步驟,我推薦第一個。

更清楚了嗎?我希望它有幫助。

+0

thx,但你可以發佈一個更完整的例子嗎?顯示實施。 – FooBar

+0

當然,我現在在工作,那是我能記得的那段代碼。我將在20分鐘後離開,所以儘快我會給你一個更完整的代碼。 – HericDenis

+0

Ok @FooBar現在我回家了我會幫你的(: – HericDenis

1

我會使用計時器或創建動畫。您可以創建動畫,以完成各種事情,包括隨着時間的推移改變透明度。

這裏的Android Documentation的動畫資源

0

我相信有可能是這樣的複雜的方法,但我需要我用的是有很多優點的簡單方法: 我首先創建記錄座標的(以及所需的任何其它數據)的每一個點(而不是現場繪製點),然後使用定時器(最好是Android處理程序)重現它們。這也提供了很多的可能性,而實際繪圖:暫停,走得更快/更慢,倒退,... 我不知道這種方法是否可以用於複雜的圖紙,但它可以繪製形狀,曲線,表面等