wea*_*ire 8 android android-layout android-canvas android-view
我从头开始创建自定义视图.扩展View和覆盖onDraw().当关闭动画视图时,我使用偏移生成自定义动画.例如.
while(!isOnTop){
mOffset++;
//draw the component a a it higher using the offset
if(position == 0)
isOnTop==true;
invalidate();
}
Run Code Online (Sandbox Code Playgroud)
我的想法是我的框架来自于自我.问题是只能通过在同一屏幕上滚动列表视图来使此视图无效.
这种"共享失效()"导致我的动画滞后.那么有没有办法摆脱这种滞后?
您是否有其他建议在共享环境中执行动画?使用计算偏移量的单独线程创建动画也需要强制invalidation()调用来显示动画(如果我错了,请纠正我).
唯一的解决方案是执行动画,例如10个具有更大步骤的失效请求?它将缓解延迟,但我认为我可以使用不同的方法.
hac*_*bod 22
"什么是最好的"当然在很大程度上取决于你想要做什么.你还没有说你想要完成什么,所以我们只能猜测你最适合自己的东西.
这是一些简单的事情:
如果要为位图帧设置动画,请使用AnimationDrawable:http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html
如果要为层次结构中的视图移动设置动画,请使用视图动画框架:http://developer.android.com/guide/topics/graphics/view-animation.html
新的更通用的动画框架可以做更多的东西,通常更容易使用:http://developer.android.com/guide/topics/graphics/animation.html.这在Android 3.0+中原生可用,但也可以在支持v7库的Android API 7级中使用.
如果要编写作为其视图层次结构的集成部分的自定义窗口小部件并手动执行其自己的动画绘制,则可以使用处理程序对更新进行计时(通常,您需要在每个invalidate()之间60fps或20ms)和然后在你的onDraw()方法中,基于SystemClock.uptimeMillis()将视图的状态绘制为动画开始时的增量.
这是使用Handler的简单重复无效:
long mAnimStartTime;
Handler mHandler = new Handler();
Runnable mTick = new Runnable() {
public void run() {
invalidate();
mHandler.postDelayed(this, 20); // 20ms == 60fps
}
}
void startAnimation() {
mAnimStartTime = SystemClock.uptimeMillis();
mHandler.removeCallbacks(mTick);
mHandler.post(mTick);
}
void stopAnimation() {
mHandler.removeCallbacks(mTick);
}
Run Code Online (Sandbox Code Playgroud)
由于这个问题有一些兴趣,我会回答。
最好的方法是拥有一个单独的画布线程。“单独的”画布只能通过SurfaceView. LunarLanding 就是这种用途的一个很好的例子。每个帧都是单独计算的,主视图只共享 CPU 时间,而不共享绘制时间。因此,即使结合顶部的常规视图和底部的动画视图,速度也会更快。
但如果您处于该共享环境中,则必须设置一个间隔。该间隔用于 FPS 上限。如果您不设置 FPS 上限,那么 CPU 将疯狂运行,以获取良好的动画(如果SurfaceView它是单独的)。将其限制在 60fps 甚至更低,可以有效地绘制所有视图,而不会造成 CPU 过载。
因此,请从 API 演示中查看登月的绘制线程并设置 FPS 上限。
private long timeNow;
private long timeDelta;
private long timePrevFrame;
private void capFps(int fps) {
timeNow = System.currentTimeMillis();
timeDelta = timeNow - timePrevFrame;
try {
Run Code Online (Sandbox Code Playgroud)
//ps 对于60FPS你总是可以设置16而不是1000/fps以避免每次计算
Thread.sleep((1000 / fps) - timeDelta);
} catch (InterruptedException e) {
}
timePrevFrame = System.currentTimeMillis();
}
Run Code Online (Sandbox Code Playgroud)
然后绘图线程将如下所示:
@Override
public void run() {
Canvas c;
while (run) {
c = null;
sleepFps(60, false);
try {
synchronized (surfaceHolder) {
c = surfaceHolder.lockCanvas(null);
widgetView.doDraw(c);
}
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14334 次 |
| 最近记录: |