Last active
November 7, 2018 02:30
-
-
Save roipeker/66bb7a0565df24336e3c748d98d5c28f to your computer and use it in GitHub Desktop.
Custom TabBar for Feathers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ================================================================================================= | |
// | |
// Created by Rodrigo Lopez [roipeker™] on 06/11/2018. | |
// | |
// ================================================================================================= | |
package { | |
import feathers.controls.TabBar; | |
import feathers.controls.ToggleButton; | |
import flash.geom.Rectangle; | |
import starling.animation.Transitions; | |
import starling.core.Starling; | |
import starling.display.DisplayObject; | |
import starling.display.Quad; | |
public class AnimatedTabBar extends TabBar { | |
// helper Rectangle. | |
private var rect:Rectangle = new Rectangle(); | |
private var _bar:Quad; | |
private var _bg:Quad; | |
// set to ::specialAnimation or ::simpleAnimation. | |
// null for no animation. | |
public var animationFunction:Function = specialAnimation; | |
public function AnimatedTabBar() { | |
super(); | |
} | |
override protected function initialize():void { | |
super.initialize(); | |
_bg = new Quad(4, 4, 0x444444); | |
_bar = new Quad(4, 2, 0xffffff); | |
_bar.visible = false; | |
addChild(_bg); | |
addChild(_bar); | |
if (_selectedIndex != -1) { | |
// 1 frame delay, waiting feathers to finish tabs UI invalidation. | |
Starling.juggler.delayCall( showSelected, 0, false ); | |
} | |
} | |
override protected function refreshTabs(isFactoryInvalid:Boolean):void { | |
super.refreshTabs(isFactoryInvalid); | |
addChild(_bar); | |
} | |
override protected function draw():void { | |
super.draw(); | |
if (isInvalid(INVALIDATION_FLAG_SIZE)) { | |
_bg.readjustSize(actualWidth, actualHeight); | |
_bar.y = actualHeight - _bar.height - 2; | |
} | |
} | |
override protected function commitSelection():void { | |
super.commitSelection(); | |
// this will be called before the delay, but the tab will have no children built, | |
// so it will exit the method. | |
showSelected( true ); | |
} | |
private function showSelected( useAnimation:Boolean = true ):void { | |
var tab:ToggleButton = toggleGroup.selectedItem as ToggleButton; | |
Starling.juggler.removeTweens(_bar); | |
if (!tab) { | |
// hide effect? | |
_bar.width = _bar.x = 0; | |
_bar.visible = false; | |
} else { | |
_bar.visible = true; | |
if (tab.numChildren == 0) { | |
trace("Tab buttons requires children."); | |
return; | |
} | |
// not the most performant approach, but works. | |
// Choose by default icon or label, whatever is available first. | |
var obj:DisplayObject = tab.getChildAt(tab.numChildren - 1); | |
obj.getBounds(tab.parent, rect); | |
if (animationFunction && useAnimation ) { | |
animationFunction(); | |
} else { | |
_bar.x = rect.x; | |
_bar.width = rect.width; | |
} | |
} | |
} | |
//============================ | |
// ANIMATION TYPES -- | |
//============================ | |
public function simpleAnimation():void { | |
Starling.juggler.tween(_bar, .25, { | |
x: rect.x, width: rect.width, | |
transition: Transitions.EASE_IN_OUT | |
}); | |
} | |
public function specialAnimation():void { | |
// offset the initial X movement for the first half of the tween. | |
var initialMoveX:Number = 0; | |
var moveRight:Boolean = _bar.x < rect.x; | |
var halfDistance:Number = Math.abs(rect.x - _bar.x) / 2; | |
if (moveRight) { | |
Starling.juggler.tween(_bar, .3, { | |
x: _bar.x + initialMoveX, width: halfDistance, transition: Transitions.EASE_IN | |
}); | |
Starling.juggler.tween(_bar, .4, { | |
delay: .3, x: rect.x, width: rect.width, transition: Transitions.EASE_OUT | |
}); | |
} else { | |
Starling.juggler.tween(_bar, .3, { | |
x: rect.x + halfDistance, | |
width: halfDistance + _bar.width - initialMoveX, | |
transition: Transitions.EASE_IN | |
}); | |
Starling.juggler.tween(_bar, .4, { | |
delay: .3, x: rect.x, width: rect.width, transition: Transitions.EASE_OUT | |
}); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment