0

我正在制作动态壁纸(实际上是我的第一个 :)),我似乎陷入了僵局:

如果您还没有通过变量名和代码猜到的话,那么有问题的动态壁纸就是一个时钟。它的组件必须遵循非常严格的度数/时间比率(总共会有十几个位图以不同的速率、不同的方向旋转(一些遵循相同的比率/规则))。

无论如何...就目前而言,添加的每个额外位图几乎都会使 drawFrame() 的执行长度增加一倍。如果我要停在 3 个运动部件上,那还不错,看起来还可以;但是将位图数量增加 9 个(甚至增加 2 个或 3 个)并且帧速率变得不可接受。

我没有按照建议每回合重新解码位图...

我应该怎么做才能纠正这种情况?

我正在考虑研究 openGL 表面/引擎,但我在 SO 上看到了一个交换,其中用户一次处理 100 多个位图没有问题(Android drawBitmap Performance For lots of Bitmaps?),这让我希望我能做同样的事情.

我还在相应的可绘制 -_dpi 文件夹中包含了每个图像的适当版本。图像不是特别大,文件大小相当小,因为有很多颜色和很多透明部分(最大 = 屏幕尺寸,最小 = 90%widthscreen/50% 屏幕高度 - 所以对于 xhdpi 720 1280 最大和 565 *562 最小)

所以基本上,根据我的研究,我的代码应该是活泼的……但事实并非如此。显然我错了:),请帮我做对!

非常感谢。

void drawFrame()
    {
        timeSinceLastRun = AnimationUtils.currentAnimationTimeMillis() - timeAtLastRun;
        timeAtLastRun = AnimationUtils.currentAnimationTimeMillis();

        final SurfaceHolder holder = getSurfaceHolder();
        Canvas c = null;
        try
        {

            c = holder.lockCanvas();
            if (c != null)
            {
                c.save();
                c.drawColor(0xff000000);
                drawTouchPoint(c);
                if(isItPhase1)
                {
                    skipToPosition(c,0,0,false,1);
                    skipToPosition(c,1,1,false,2);
                    skipToPosition(c,2,2,true,3);
                }
                else
                {

                    animateGears(c,0,0,0,0);
                    animateGears(c,1,1,1,1);
                    animateGears(c,2,2,2,2);
                }

                c.restore();
            }
        }
        finally
        {
            if (c != null)
                holder.unlockCanvasAndPost(c);
        }

        mHandler.removeCallbacks(mDrawPattern);
        if (mVisible)
        {
            mHandler.postDelayed(mDrawPattern, 1000/25);
        }
    }

    private void skipToPosition(Canvas c, int xP, int yP, boolean lastTest, int timeBasis)
    {
        if(isItFirstRun)
        {
            gears[0] = BitmapFactory.decodeResource(getResources(), 
                    l.werner.mechanicalclocklivewallpaperversion0001.R.drawable.seconds_gear);

            gears[1] = BitmapFactory.decodeResource(getResources(), 
                    l.werner.mechanicalclocklivewallpaperversion0001.R.drawable.minutes_gear);

            gears[2] = BitmapFactory.decodeResource(getResources(), 
                    l.werner.mechanicalclocklivewallpaperversion0001.R.drawable.hours_gear);

            m[0] = new Matrix();
            m[1] = new Matrix();
            m[2] = new Matrix();
            m2[0] = new Matrix();
            m2[1] = new Matrix();
            m2[2] = new Matrix();

            x[0] = 0;
            x[1] = 0;
            x[2] = 0;
            y[0] = 0.006f;
            y[1] = 0.0001f;
            y[2] = (0.000001666666666666666666666666666666667f);
            timeSinceLastRun = 0;
            movementPerTurn = 0;
            isItFirstRun = !isItFirstRun;
        }
        Calendar cal = Calendar.getInstance();
        float second = cal.get(Calendar.SECOND);
        float minute = cal.get(Calendar.MINUTE);
        float hour = cal.get(Calendar.HOUR);
        if(timeBasis == 1)
            x[xP] = x[xP] + (360f*(second/60f));
        else if(timeBasis == 2)
            x[xP] = x[xP] + (360f*(minute/60f));
        else if(timeBasis == 3)
            x[xP] = x[xP] + (360f*(hour/12f));
        if(lastTest)
        {
            isItPhase1 = !isItPhase1;
        }
    }

    void animateGears(Canvas c, int xP, int yP, int g, int mP)
    {
        movementPerTurn = y[yP] * timeSinceLastRun;

        x[xP] = x[xP] + movementPerTurn;

        m[mP].setRotate(((float)x[xP]*1f), 0.5f*gears[g].getWidth(),0.5f*gears[g].getHeight());
        m2[mP].setTranslate(c.getWidth()/2f - 0.5f*gears[g].getWidth(),
                c.getHeight()/2f - 0.5f*gears[g].getHeight());
        m[mP].setConcat(m2[mP], m[mP]);

        c.drawBitmap(gears[g], m[mP] , null);
    }
4

1 回答 1

0

考虑为动画使用单独的线程。您可以使用我在 GitHub 上发布的动态壁纸模板轻松测试此解决方案,看看它是否会让您有所作为。

于 2013-09-23T06:36:10.650 回答