【发布时间】: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 吗?我遇到的问题是,如果它与一个HorizontalScrollView(facebook菜单实现)和一个带有包含许多SurfaceViews的viewpager的片段一起使用,如果你将ViewPager滚动到索引1然后单击facebook菜单,索引0上的SurefaceView会重叠facebook 菜单,如果我把 ViewPager 隐藏起来,那将是一个很好的黑匣子。
-
正如 barconr 提到的最好的想法是异步任务。它实际上是线程类的包装器。我认为表面视图对于您想要的东西来说太过分了。异步类通常处理进度条。他们应该适合定制的。看一些代码会有所帮助。
标签: android view surfaceview