1

I have a card a game in which the person chooses the card and drags (done through translate animation) and then when let go it moves to the center of the screen where have an imageView place holder. At the animationEnd I set the image view to that card and can invalidate on each view on the screen. What I dont understand is that when I call invalidate then the card looks like it left some trails (shadows from the translate animation). When I call postInvalidate, it gets drawn properly. Why is that??

AnimationEnd code:

@Override
public void onAnimationEnd(Animation arg0) {

    if(card == null){
        MyApplication.SWERR(null);
        busy = false;
    }
    card.getCardImage().setVisibility(View.INVISIBLE);
    Drawable drawable = card.getCardSuitNumber().getDrawable(mContext);
    finalDestIV.setBackgroundDrawable(drawable);
    finalDestIV.setVisibility(View.VISIBLE);
    invalidateAll();

    PlayerStatus p = mGameMonitor.getPlayerStatusFromPlayerEnum(GameConstants.PLAYERS.P1);
    p.handleCardChosen(card);
    cardReleased = false;
    p.setPlayerLock(false);
    card = null;




}

InvalidateAll method

private void invalidateAll(){
    rootLayout.postInvalidate();
    for (int i=0; i<rootLayout.getChildCount();i++){
        View v = rootLayout.getChildAt(i);
        v.postInvalidate();
    }
}
Snake
  • 14,228
  • 27
  • 117
  • 250

1 Answers1

1

Typical problem of novice Android developers. Please look into the description of the invalidate method. According to the Google documentation:

Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().

So, I suppose onAnimationEnd is calling from non-UI thread (probably animation thread). I think if you avoid the API policy it may lead to unexpected behavior and may differs between different Android versions. Calling invalidate from non-UI thread can interrupt some UI operations (or brake some logic) in Android system which makes some misbehavior.

Look also here: What does postInvalidate() do?

Community
  • 1
  • 1
Roman
  • 350
  • 2
  • 8
  • Thank you, the OnAnumationEnd is called when the animation finished. I am using the default Animation class provided by Android. So I assume it is running on different thread then – Snake Jul 11 '13 at 17:14