在延迟的画布上画画 - "make onDraw()减速"

Foo*_*Bar 6 animation android draw android-canvas

我在android中使用drawCircle和drawPoint等画布函数.这很好用.

但现在的问题是延迟绘制这些不同的项目,所以它看起来像一个动画.

我应该使用什么样的机制?尝试过异步,但我不喜欢这样做.

我应该使用某种只是间隔绘制的计时器,还是有其他巧妙的方法来做到这一点?

Her*_*nis 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);
        }
    };
Run Code Online (Sandbox Code Playgroud)

然后,当我想启动时间管理器时,我只需调用 mTimeManager.run() ,它将开始Observer定期通知我的 s (之前添加的)。

如果您出于某种原因需要停止计时器或其他操作,您只需这样做:

    mHandler.removeCallbacks(mTimeManager);
Run Code Online (Sandbox Code Playgroud)

[编辑-更完整的代码]

好吧,让我们说得更清楚,首先我制作了一个像这样的自定义 Observable 对象[这是可选的]:

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

        @Override
        public void notifyObservers(Object data) 
        {
            setChanged();
            super.notifyObservers(data);
        };
    };
Run Code Online (Sandbox Code Playgroud)

原因只是因为我无法在 Observable 类之外调用 setChanged() - 它是受保护的,如果它没有更改,它不会通知任何观察者。

其他声明与之前所示的保持相同,现在我需要TimeManager在某个地方启动它,我的应用程序是一个 LiveWallpaper,我将所有渲染内容放入一个扩展 a 的类中,Thread但你不一定需要它,我创建了一个名为 的方法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
        }
    }
Run Code Online (Sandbox Code Playgroud)

它是双重的:

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

好的,现在我们可以启动和停止时间管理器,但是谁在听呢?没有人!所以让我们添加它们:在渲染器的构造函数中,我ObservermObservable对象添加了一些,其中之一是渲染器本身,因此我的渲染器扩展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
        }
    }
Run Code Online (Sandbox Code Playgroud)

添加观察者你只需做mObservable.addObserver(THE_OBJECT - Implements Observer)

您可以看到,每次收到通知时,我都不会重新渲染我的内容,那是因为我将这个 TimeManager 用于其他想法,而不仅仅是刷新,例如Canvas更新我想在内部绘制的对象的位置。

所以,你需要放慢绘图速度的是改变你的对象在时间流逝时内部变化的方式,我的意思是你的圆和点等,或者你可以改变你的时间步长,我推荐第一个。

是不是更清楚了?我希望它有帮助。