Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/214.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在画布上延迟绘制-“;使onDraw()慢下来;_Android_Animation_Android Canvas_Draw - Fatal编程技术网

Android 在画布上延迟绘制-“;使onDraw()慢下来;

Android 在画布上延迟绘制-“;使onDraw()慢下来;,android,animation,android-canvas,draw,Android,Animation,Android Canvas,Draw,我在android中使用类似drawCircle和drawPoint的画布功能。 这个很好用 但是现在的问题是要延迟绘制这些不同的项目,所以它看起来像一个动画 我应该使用什么样的机制?我尝试过异步,但我不喜欢这样做 我应该使用一种只需按间隔绘制的计时器,还是有其他聪明的方法可以做到这一点?我会使用计时器,或者创建动画。您可以创建可以执行各种操作的动画,包括随时间改变透明度 下面是动画资源的示例我使用此策略,首先声明一个处理程序和一个Runnable: private final Obse

我在android中使用类似drawCircle和drawPoint的画布功能。 这个很好用

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

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


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

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


下面是动画资源的示例

我使用此策略,首先声明一个处理程序和一个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(),它就会开始定期通知我的
观察者
s(以前添加的)

如果出于某种原因需要停止计时器或其他操作,请执行以下操作:

    mHandler.removeCallbacks(mTimeManager);
[编辑-更完整的代码]

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

    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,我将所有渲染内容都放入一个类中,该类扩展了
线程
,但您不必这样做,我创建了一个名为
resumeDrawing()
,名为,这个函数在
super.start()之后调用
在我的
线程
类的
public synchronized void start()
@Override
中,该方法如下所示:

    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.");
        }
    }
好的,现在我们可以启动和停止时间管理器,但是谁在听呢?没有人让我们添加它们:在我的渲染器的构造函数上,我向我的
mObservable
对象添加了一些
Observer
s,其中一个是渲染器本身,因此我的渲染器扩展了
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(对象-实现观察者)

您可以看到,每次收到通知时,我都不会重新渲染我的东西,这是因为我使用此时间管理器进行其他思考,而不仅仅是刷新
画布
,比如更新我要在内部绘制的对象的位置

所以,你需要放慢画图的速度,改变你的物体随着时间的推移而内部变化的方式,我是指你的圆和点等,或者你可以试试你的时间步,我推荐第一步


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

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

thx,但您能提供一个更完整的示例吗?显示实现。当然,我现在正在工作,这是我能记住的一段代码。我将在20分钟内离开,所以我会给你一个更完整的代码。好的,现在我在家,我会帮助你的:(@ @ FooBar,请考虑投票和标记,如果它对你有用的话。谢谢你的回答。它帮助了我一些,所以我现在在正确的轨道上。