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

时间:2012-10-10 18:56:19

标签: android animation android-canvas draw

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

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

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

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

3 个答案:

答案 0 :(得分: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(之前添加的)。

如果您因某种原因需要停止计时器或其他事情,请执行此操作:

    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,我将所有渲染内容放到一个扩展Thread的类中但是你我不需要这样做,我制作了一个名为resumeDrawing()的方法,这个方法是在我super.start(); @Override public 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.");
        }
    }

它是双重的:

Observer

好的,现在我们可以开始和停止时间管理员,但是谁在听?没有人!所以让我们添加'em:在我的渲染器的构造函数中,我向mObservable对象添加了一些Thread,其中一个是渲染器本身,所以我的渲染器扩展Observer并实现{ {1}}:

    @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,就像更新我想要的对象的位置一样在内部画画。

所以,你需要减慢绘图的速度是改变你的对象在内部时间变化的方式,我的意思是你的圈子和点等,或者你可以冒险你的时间步,我推荐第一个。< / p>

更清楚了吗?我希望它有所帮助。

答案 1 :(得分:1)

我会使用计时器,或创建动画。您可以创建可以执行各种操作的动画,包括随时间更改透明度。

这是动画资源的Android Documentation

答案 2 :(得分:0)

我相信可能有复杂的方法来做到这一点,但是为了我的需要,我使用了一个有很多优点的简单方法: 我首先为绘图的每个点创建记录坐标(以及所需的任何其他数据) - 而不是在现场绘制点 - 然后使用计时器(Android处理程序,最好再现它们) )。实际绘图时,这也提供了很多可能性:暂停,更快/更慢,倒退,...... 我不知道这种方法是否可以用于复杂的绘图,但它可以用于绘制形状,曲线,曲面等。