I wrote a simple sprite animation canvas view, and in my application this view is held inside a GridView. Generally the sprite view flow is to draw the frame on the canvas, then call invalidate(), so the UI thread will come back to draw the next frame.
This code works fine when the view is placed inside any "normal" layout, but inside GridView the animation stops after a few frames.
Any idea for resolution anyone?
@Override
protected void onDraw(Canvas canvas)
{
if (getVisibility() == View.VISIBLE) {
render(canvas, System.currentTimeMillis());
invalidate();
}
}
private Rect dest;
private void render(Canvas canvas, long currentTime)
{
if (currentTime >= mTimer + mMiliscPerFrame) {
mTimer = currentTime;
calculateFrame();
mDrawRect.Left = (int)((float)mSpriteWidth * mFrameColomn + 0.5f);
mDrawRect.Right = (int)((float)mSpriteWidth * (mFrameColomn + 1) + 0.5f);
mDrawRect.Top = (int)((float)mSpriteHeight * mFrameRow + 0.5f);
mDrawRect.Bottom = (int)((float)mSpriteHeight * (mFrameRow + 1) + 0.5f);
++mCurrentFrame;
}
if (dest == null)
dest = new Rect(0, 0, destinationWidth(canvas), destinationHeight(canvas));
else {
dest.setRight(destinationWidth(canvas));
dest.setBottom(destinationHeight(canvas));
}
canvas.DrawBitmap(mBitmap, mDrawRect, dest, null);
}
OK. I did some digging into the Android code.... The AdapterView which is the superclass of both ListView and GridView is blocking the layout requests of it's siblings. I tried to tackle it by writing my own MyGridView derived from GridView. To do that I had to use and manipulate non public API functions and members. For commercial projects, this is not a possibility. My final resolution was to re-implement my code using GridLayout inside ScrollView instead.