【问题标题】:Alternative to SurfaceView?SurfaceView 的替代品?
【发布时间】:2012-11-02 22:17:41
【问题描述】:

我正在制作一个自定义 ProgressBar,它有一个可以旋转的位图。如果我使用 View.invalidate FPS 会卡顿; deltaTime 将增加 40 多次。逻辑和渲染几乎是即时的,但无效调用使其变慢。所以我正在尝试 SurfaceView,问题是我之前在将 SurfaceView 与其他视图组装时遇到了问题,我不想使用它。 SurfaceView 和 View.invalidate 是否有任何替代方案,还是我坚持使用它们?

编辑:

为了进一步澄清,我正在制作一个自定义 View,它是一个 intermediate ProgressBar。所以 View 就是 ProgressBar。我现在也没有下载任何东西,我只是想为我的视图获得最大 FPS。一些代码:

MyProgressBar extends View implements Runnable

还有run()

calculateNewRotation();
invalidate();
post(this);

calculateNewRotation() 的位置

long now = SystemClock.uptimeMillis();
int deltaTime = (int) (now - mLastRender);
mLastRender = now;
mSpinRotation += deltaTime * SPIN_SPEED_PER_MILLISECOND_CLOCKWISE;

Post(this) 指的是 MyProgressBar,它将永远循环,直到我另有说明。

在我的 onDraw() 中

mCamera.save();
mCamera.rotateZ(mSpinRotation);
mCamera.getMatrix(mMatrix);
mCamera.restore();

mMatrix.preTranslate(-mTranslatePivotX, -mTranslatePivotY);
mMatrix.postTranslate(mTranslatePivotX + mCenterX, mTranslatePivotY + mCenterY);

canvas.drawBitmap(mSpinBitmap, mMatrix, mSpinBitmapPaint);

calculateNewRotation() 的时间 = 1 毫秒。

onDraw() 的时间 = 1 毫秒。

问题是总时间通常在 40 毫秒以上。我的解决方案是使用 SurfaceView,但我不喜欢使用透明像素绘制表面的视图,因此将显示底层表面。我正在寻找的是一个视图,我可以随时获得画布,最好每 16 毫秒获得 60 FPS。现在,有这样的观点吗?

【问题讨论】:

  • 被他们困住了?他们绝对没问题。这是您使用它们的方式。
  • @Doomsknight 那么为什么我会因无效而导致 FPS 卡顿?我的逻辑/渲染几乎是瞬间完成的。
  • 除非我弄错了,否则无效会导致 UI 线程在下次方便时更新。这并不意味着立即。选项是一个单独的线程来更新它。看看登月的例子。
  • @Doomsknight 对,那么我需要使用 SurfaceView 吗?我遇到的问题是,如果它与一个Horizo​​ntalScrollView(facebook菜单实现)和一个带有包含许多SurfaceViews的viewpager的片段一起使用,如果你将ViewPager滚动到索引1然后单击facebook菜单,索引0上的SurefaceView会重叠facebook 菜单,如果我把 ViewPager 隐藏起来,那将是一个很好的黑匣子。
  • 正如 barconr 提到的最好的想法是异步任务。它实际上是线程类的包装器。我认为表面视图对于您想要的东西来说太过分了。异步类通常处理进度条。他们应该适合定制的。看一些代码会有所帮助。

标签: android view surfaceview


【解决方案1】:

您是否在 UI 线程上进行长时间操作(通常是需要进度条的原因)?您的 UI 线程应该在另一个线程或异步任务处理长操作时更新进度条。

【讨论】:

  • 当我测试我的自定义实现时,我根本不做任何工作,我只是让我的进度条不停地旋转。
  • 根据您的绘制方法计算增量时间。 Invalidate() 可能实际上不会重绘屏幕,因此在其他方法/线程中计算增量时间是没有意义的。在 onDraw() 中计算增量时间将确保它自上次绘制以来具有正确的值。试试看,看看你的时间是否有所改善。
  • 尝试调用 postInvalidate() 而不是 invalidate(),有改善吗?
  • 没有改善,还是卡顿。。我想我得再看一遍代码了。
  • 或许把run()和post()的全部内容贴出来?
【解决方案2】:

我最后所做的是,当我绘制图像时,我将旋转值更新 1。在快速和慢速手机上,它看起来会很平滑,但速度会有所不同。在快速手机上,它可能每秒绘制 60 帧,即每秒 60 度,而每秒 10 帧的慢速手机会使旋转每秒旋转 10 度。所以说到底是想让它们以相同的速度旋转还是让它看起来不错,我选择了后者。

编辑

我想我可以设置每秒最大帧数,这样快速手机就会受到限制,从而缩小快速手机和小型手机之间的差距。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2012-01-25
    • 2015-08-05
    • 2011-01-01
    相关资源
    最近更新 更多