Thursday, September 13, 2012

Sencha Touch - Add callback function to animateActiveItem

Hello,

Recently I was working on a sencha touch project and faced an interesting issue. There was a requirement to adjust the layout after animation is completed. When we do animateActiveItem, you might not have noticed this but animateActiveItem is asynchronous. By default sencha touch has animation duration of 250ms. So  when you write following statement.

this.getMain().animateActiveItem(item,{ type: 'slide', direction: 'right'});
this.getMain().query('#element').hide();

You will notice that your element is hidden before animation is completed. You may increase the duration to see this.


this.getMain().animateActiveItem(item,{ type: 'slide', direction: 'right', duration:2000});
this.getMain().query('#element').hide();


So sometimes you might have annoying effects like, some of your UI jumps. To avoid this and have smooth transition, callback is necessary so UI changes can be adjusted after animation is completed. So how to do that? Here is the trick

Override animateActiveItem function of Ext.container


Ext.override(Ext.Container, {
    animateActiveItem: function(activeItem, animation, callback) {
        var layout = this.getLayout(),
            defaultAnimation;
     
        if (this.activeItemAnimation) {
            this.activeItemAnimation.destroy();
        }
        this.activeItemAnimation = animation = new Ext.fx.layout.Card(animation);
        if (animation && layout.isCard) {          
            animation.setLayout(layout);
            defaultAnimation = layout.getAnimation();          
            if (defaultAnimation) {
                defaultAnimation.disable();
                animation.on('animationend', function() {                  
                    defaultAnimation.enable();
                    animation.destroy();

                    if(callback){
                          callback();  
                    }
                }, this);
            }else{
                animation.on('animationend', function() {                  
                    animation.destroy();
                    if(callback){
                          callback();  
                    }
                }, this);
            }
        }
        return this.setActiveItem(activeItem);
    }
});

See the following code carefully.


if(callback){
     callback();  
}

I have added callback function as a parameter in method and that will be invoked when application end. I added this in both if and else part so it will be invoked if you have specified the animation or you are using default animation.

Now your animateActiveItem function call is changed. See the code below.

this.getMain().animateActiveItem(item,{ type: 'slide', direction: 'right', duration:2000},function(){
//your callback function code.
});

See the last parameter, that is your callback function.

Hope this posts helps you.

No comments:

Post a Comment