2012-10-10 21 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处理程序)重现它们。这也提供了很多的可能性,而实际绘图:暂停,走得更快/更慢,倒退,... 我不知道这种方法是否可以用于复杂的图纸,但它可以绘制形状,曲线,表面等