ViewSwitcher AnimationStart/End

MichaelMuegelMichaelMuegel US ✭✭
edited October 2012 in Xamarin.Android

In a test, ViewSwitcher AnimationStart and AnimationEnd events are not firing after ShowNext() is called and animation starts/completes. Before I filed a bug report/sample, I wanted to check whether my understanding of this event is correct.

Posts

  • JonathanPryorJonathanPryor USXamarin Team Xamurai

    This may be by design, as I think things may be confusingly named.

    The ViewGroup.AnimationStart and ViewGroup.AnimationEnd events are for the Animation.IAnimationListener property and ViewGroup.LayoutAnimationListener interface; that is, instead of implementing Animation.IAnimationListener yourself and setting the ViewGroup.LayoutAnimationListener property, you can instead subscribe to the ViewGroup.AnimationStart and/or ViewGroup.AnimationEnd.

    Meanwhile, ViewSwitcher animations are set from the ViewAnimator.InAnimation and ViewAnimator.OutAnimation properties.

    I suspect that for ViewSwitcher you should be preferring the ViewAnimator.InAnimation and ViewAnimator.OutAnimation properties.

  • MichaelMuegelMichaelMuegel US ✭✭
    edited October 2012

    Hi Jon. I am a bit confused still:

    you can instead subscribe to the ViewGroup.AnimationStart and/or
    ViewGroup.AnimationEnd

    That is what I did. My views animate the switch fine as I was using InAnimation and OutAnimation to set animations from some resources:

    VS = FindViewById<ViewSwitcher>(Resource.Id.View_Switcher);
    VS.InAnimation = AnimationUtils.LoadAnimation(this, Resource.Animation.slide_left_in);
    VS.OutAnimation = AnimationUtils.LoadAnimation(this, Resource.Animation.slide_right_out);
    VS.AnimationStart += delegate
    {
       MLog.Info("VS.AnimationStart event");               
    };
    VS.AnimationEnd += delegate
    {
       MLog.Info("VS.AnimationEnd event");
    };
    

    But the events never get fired. The logging code never executes.

  • JonathanPryorJonathanPryor USXamarin Team Xamurai

    I believe that this is by design, if only because I'm starting to have trouble tracing through the ViewGroup and related code.

    In particular, consider the ViewGroup.setLayoutAnimationListener (source) method:

    Specifies the animation listener to which layout animation events must be sent. Only onAnimationStart(Animation) and onAnimationEnd(Animation) are invoked.

    (Emphasis mine.)

    I suspect that Animation.AnimationListener instance, as provided to ViewGroup.setLayoutAnimationListener() (and thus the ViewGroup.AnimationStart and ViewGroup.AnimationEnd events) is only used on layout events. View switching, on the other hand, isn't a layout event, and thus bypasses the Animation.AnimationListener.

    Specifically, ViewGroup.setLayoutAnimationListener() sets the ViewGroup.mAnimationListener field, which is only used by ViewGroup.dispatchDraw() (which is only used to display child views) and ViewGroup.notifyAnimationListener(), which in turn is invoked by ViewGroup.dispatchDraw(). Therefore, ViewGroup.mAnimationListener is only used for rendering child views (via dispatchDraw()); see also View.buildDrawingCache(), View.createSnapshot(), View.draw(), View.draw().

    I'm probably overlooking this too much though; I suspect the real "problem" is ViewAnimator.showOnly() (called by ViewAnimator.showNext(), ViewAnimator.setDisplayedChild(), etc.), which does two things:

    1. Set the child view's visibility
    2. Start the animation within the context of the child view.

    Note that ViewAnimator is busy working to ensure that only one child is ever visible and uses the View animation methods (which are not overridden by ViewGroup, so View.startAnimation() is completely unrelated here).

  • Thanks for explanation Jon. Cheers.

Sign In or Register to comment.