Hallo tabbar supports item click event. However spark tabBar doesnot supports itemClick event.
is there way to listen itemclick event in SPARK TABBAR
thanks all
Spark components inheriting from ListBase no longer dispatch ItemClick events. You can use the IndexChangeEvent event instead though. It has a property newIndex that tells you which is the newly selected item (or tab in this particular case).
<s:TabBar dataProvider="{dp}" change="trace('selected: ' + event.newIndex)" />
One big difference with the old ItemClick is that this event is only dispatched when the selected item actually changes (as opposed to whenever it is clicked). If you really want the behaviour of ItemClick back, you can create a custom ItemRenderer that dispatches an
ItemClick event.
If you want to react on every click there are a few approaches. Here are two of them:
1./ Create a custom ItemRenderer that dispatches an ItemClick event.
.
public class TabBarButton extends ButtonBarButton {
override public function initialize():void {
super.initialize();
addEventListener(MouseEvent.CLICK, fireItemClick);
}
private function fireItemClick(event:MouseEvent):void {
owner.dispatchEvent(new ItemClickEvent(
ItemClickEvent.ITEM_CLICK, false, false, null, itemIndex, null, data
))
}
}
You can now use it like this:
<s:TabBar id="tabBar" dataProvider="{dp}"
itemRenderer="net.riastar.TabBarButton" />
tabBar.addEventListener(ItemClickEvent.ITEM_CLICK, onItemClick);
2./ Another approach would be to just listen for any click event on the TabBar and use event.target to find the clicked tab:
<s:TabBar dataProvider="{dp}" click="trace(event.target)" />
//traces tabBar.TabBarSkin1.dataGroup.TabBarButton1
Note that this is a direct answer to your question, but I actually don't think you should do this. In most cases IndexChangeEvent.CHANGE will do just fine.
Related
I often have the requirement to dispatch a flash.events.Event with soem custom String text, like:
protected function mouseClicked(event:Event) {
//here I'd want to notify anyone interested in the button click,
//and also transfer the name of the button (or whatever) that was clicked - assume some dynamic value
dispatchEvent(new Event("myMouseEvent"), button.name));
}
Of course the above event is invalid. But is there any event that can be used for that type of events? Maybe the TextEvent, but I don't know if I'd be misusing it here.
To include additional data with your events, create a custom event class by extending Event (or any sub-class of Event) and adding your own properties. For example:
class NameEvent extends Event {
public static const NAME_CLICK:String = "nameClick";
public var name:String;
public function NameEvent(type:String, name:String) {
this.name = name;
super(type);
}
}
dispatchEvent(new NameEvent(NameEvent.NAME_CLICK, button.name));
Note that your event type strings ("nameClick" in this example) should be globally unique, otherwise listeners could get them confused with other event types. For example "click" is already expected to be a MouseEvent. I often add prefixes to my custom event types, for example "NameEvent::click".
Another option that does not require creating a custom event is to rely on the expected target to get additional data. For example:
// dispatch a custom event from a Button
dispatchEvent(new Event("myClick"));
// handler for "myClick" events on the button
function myClicked(e:Event):void {
var button:Button = e.target as Button;
trace(button.name);
}
This is not as flexible and also more fragile than using a custom event class, but sometimes a quick easy solution.
My question today is about the way we can register an event listener.
Let's say we have a Group element and inside it a custom Handler element. We want the Handler element to do something when Group triggers a custom event. Now, what is the best way to do it?
var group:Group = new Group();
var handler:Handler = new Handler();
group.addElement(handler);
Now, what is the best way to register the event listener?
1. Go on and do it from the file where we initialized the objects
group.addEventListener("CustomEvent", handler.handlerFunction);
2. Register the event listener from the Handler's class:
parent.addEventListener("CustomEvent", handlerFunction);
3. Any other way?
You can let Group class instance dispatch custom event directly on Handler class instance. Handler class would have an internal listener registered for example in constructor.
public function Handler() {
addEventListener("CustomEvent", handlerFunction);
}
Group class would dispatch event following way:
handler.dispatchEvent(new CustomEvent());
I am creating modal popup canvas window in a parent page. When I close the popup how do we get notification in parent screen that child popup is just closed. Any event for that ?
The code to show your popup:
var popup:MyPopup = new popup:MyPopup();
popup.addEventListener(CloseEvent.CLOSE, function(evt) {
PopUpManager.removePopUp(popup);
});
PopUpManager.addPopUp(popup, this, true);
Inside your MyPopup class, you will have a button for closing the popup. Simply hook the click event to publish a "CLOSE" event:
<s:Button Label="X" click="dispatchEvent(new CloseEvent(CloseEvent.CLOSE));" />
I prefer this mechanism over having the MyPopup object calling PopUpManger.removePopUp (as #Fank is suggesting) because it couples the MyPopup component to the PopUpManager which I don't like. I'd prefer the user of MyPopup to decide how to use the component.
Honestly, though, these are two very similar mechanisms to perform the same end goal.
Yes there is:
I Preffer to use the Popupmanager:
Your Popup:
There is a Button "close" call a internal function eg.closeme
private function closeMe () :void
{
PopUpManager.removePopUp(this);
}
in your Parent, you open the PopUp like this:
private function openPopup () :void
{
var helpWindow:TitleWindow = TitleWindow(PopUpManager.createPopUp(this,MyTitleWindow,fale));
helpWindow.addEventListener(CloseEvent.CLOSE, onClose);
}
protected function onClose (event:CloseEvent) :void
{
PopUpManager.removePopUp (TitleWindow(event.currentTarget));
}
My TitleWindow is the name of your class of cour popup extended by TitleWindow.
BR
Frank
Along with Brian's answer don't forget to detach the event listener. If you leave the event handler in your main app listening for an event from a child object, the child object will not be garbage collected as something is still referencing it. This is a common memory leak issue.
popup.addEventListener(CloseEvent.CLOSE, popup_CloseHandler);
private function popup_CloseHandler(event:CloseEvent):void{
event.target.removeEventListener(CloseEvent.CLOSE, popup_CloseHandler);
PopUpManager.removePopUp(popup);
}
Here's a great post about Flex's memory management if you want to delve into that further.
http://blogagic.com/163/flex-memory-management-and-memory-leaks
Can any one please tell me the difference between target and currenttarget in flex?
Sure, I've had some trouble with this too. The currentTarget property is the IEventListener you registered the event handler for. The target is the one that dispatched the event that you are currently handling. So the currentTarget changes, the target doesn't.
Check out the following example:
Sample App
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="addListeners()">
<mx:Script>
<![CDATA[
protected function addListeners():void
{
greatGrandParent.addEventListener(Event.COMPLETE, completeHandler);
grandParent.addEventListener(Event.COMPLETE, completeHandler);
aParent.addEventListener(Event.COMPLETE, completeHandler);
child.addEventListener(Event.COMPLETE, completeHandler);
// dispatch event that "bubbles", second param is "true"
// dispatched from child
child.dispatchEvent(new Event(Event.COMPLETE, true));
}
protected function completeHandler(event:Event):void
{
trace("target: ", event.target + ", currentTarget: ", event.currentTarget);
}
]]>
</mx:Script>
<mx:Panel id="greatGrandParent">
<mx:Panel id="grandParent">
<mx:Panel id="aParent">
<mx:Button id="child"/>
</mx:Panel>
</mx:Panel>
</mx:Panel>
</mx:Application>
Output
target: MyApp.greatGrandParent.grandParent.aParent.child, currentTarget: MyApp.greatGrandParent.grandParent.aParent.child
target: MyApp.greatGrandParent.grandParent.aParent.child, currentTarget: MyApp.greatGrandParent.grandParent.aParent
target: MyApp.greatGrandParent.grandParent.aParent.child, currentTarget: MyApp.greatGrandParent.grandParent
target: MyApp.greatGrandParent.grandParent.aParent.child, currentTarget: MyApp.greatGrandParent
It's a simple tree of display objects, and when the app is ready I:
Add listeners for the same event on each component in the tree.
Dispatch an arbitrary event (just for demonstration). I chose Event.COMPLETE.
Since everything has registered an eventHandler for that same event, and since I have set bubbles to true (new Event(type, bubbles)), anything in the tree, from child to greatGrandParent and beyond, that has registered an event handler for Event.COMPLETE, will run that method: completeHandler. Events travel up the chain then back down. The target is the one that dispatched the event, so since child dispatched it, it should be constant. The currentTarget is what changes.
This means that, say you want to check when you are rolling over a DataGrid in Flex, you want to know when you roll over a Checkbox inside one of the itemRenderers in the DataGrid. One way is to addEventListener on every itemRenderer's checkbox for MouseEvent.ROLL_OVER. Another way is to addEventListener to the DataGrid itself for MouseEvent.ROLL_OVER, and check what the target is on the event:
protected function dataGrid_rollOverHandler(event:MouseEvent):void
{
// event.currentTarget is DataGrid
if (event.target is CheckBox)
trace("rolled over checkbox!");
}
That's how I often use event.target.
Hope that helps,
Lance
Thus could help :
http://livedocs.adobe.com/flex/3/html/help.html?content=events_08.html#219548
You should go through tutorials on this site: http://www.adobe.com/devnet/flex/videotraining/ for an introduction to Flex before asking a question like this. Your question is covered on day 1.
I've done a lot of reading through forum posts and tutorials, but I still can't wrap my brain round events and event listeners. I have a pretty simple example, but I can't get it to work.
I have an arrayCollection of custom objects in a repeater, when one of those objects is clicked, I want a different componenet to display data associated with that object.
Here's what I have, but the listener never responds (the dispatcher seems to be working though, because the new event is created and I can see the trace with the proper output.) I suspect it is because when I call addEvent Listener, I am doing so on the wrong object. My understanding is that the object that will display the object data is the object that should have the event listener, and listen for all events of this nature, but maybe I misunderstood.
My custom event:
public class SelectObjectEvent extends Event
{
public function SelectObjectEvent(customEventString:String, myObject:customObject)
{
super(customEventString, true, false);
trace(customEventString+" "+myObject);
}
}
}
My custom object has the following function which is called on click:
public function selectObject(myObject:customObject):void
{
dispatchEvent(new SelectObjectEvent("OBJECT_SELECTED", customObject));
}
And the component I want to display the selected object has the following constructor:
public function SelectedObjectDisplayClass()
{
addEventListener("OBJECT_SELECTED", this.showObject)
}
public function showObject(event:Event):void
{
trace("Show object: "+event);
}
It's not quite clear where your last two code chunks are, but it looks like you need to be calling addEventListener on the object that extends EventDispatcher.
That is, if your second chunk belongs to a custom object called Clickable, which extends EventDispatcher and calls dispatchEvent() when clicked, then your component should be calling myClickable.addEventListener(...) where myClickable is an instance of Clickable. Does that make sense?
But assuming your 3rd code chunk is not in the same class as the second, it doesn't look like you're doing that. You're adding a listener to the class that owns the third chunk of code, which I gather is not the one that extends EventDispatcher.
Just a quick glance at your code and notice that your dispatchEvent second parameter is the class not the instance of the object. Shouldn't this be myObject?
public function selectObject(myObject:customObject):void
{
dispatchEvent(new SelectObjectEvent("OBJECT_SELECTED", **customObject**));
}