PDA

Volledige versie bekijken : duplicateMovieClip in Flex


FredericCox
%Europe/Berlin %930 %2008, 22:19
Hoi,

Ik zit al een week mijn hoofd te breken op volgend probleem:

Ik heb op een map component een 800 tal markers staan. Deze markers worden op de kaart geplaatst als een SWFLoader (denk ik toch, component is niet opensource) die marker.swf inlaadt. Hierdoor heb ik dus mooi een leuke marker op de map. Echter moet in elke marker ook nog een icoontje komen. Tot voor kort zaten die ingebakken in de marker.swf en liet ik het juiste icoon zien adhv het iconenNummer (gotoAndStop). Het zijn intussen zoveel iconen geworden dat ze nu dynamisch ingeladen moeten worden, ik heb gemerkt dat wanneer ik dit nu doe (ze met een UILoader inladen in de marker.swf) dat het geheugen ontzettend hard toeneemt en dit niet meer acceptabel is. Nu kwam ik met het idee om aan het begin van mijn app deze iconen in te laden in een SWFLoader die in een canvas zit die op zijn beurt in een viewstack zit. Die viewstack heb ik publiek gedeclareerd maar blijkbaar kan ik er alleen naar verwijzen en niet de viewstack dupliceren? Of is er een betere manier om het geheugen te beperken zoals het voorheen was?

Dit is de code waarmee ik het geprobeerd heb maar de getChildAt neemt gewoon de children uit de markersStack en dat is niet het gewenste effect :)

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="markerTest();">
<mx:Script>
<![CDATA[
import mx.containers.Canvas;
import mx.controls.SWFLoader;
import mx.core.Container;
import mx.containers.ViewStack;
import mx.core.UIComponent;
import mx.controls.Alert;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;

private function markerTest():void{
var http:HTTPService = new HTTPService;
http.url = "http://www.dev.cityfashion.tv/data/categories.xml.php";
http.addEventListener(ResultEvent.RESULT, onCategoriesLoaded);
http.send();
}
private var categories:ArrayCollection;
public var markersStack:ViewStack;
private function onCategoriesLoaded(ev:ResultEvent):void{
var tempDate:Date = new Date;
//trace("loaded xml in " + (tempDate.getTime()-startD.getTime()) + " ms");
categories = new ArrayCollection;
categories = ev.result.categories.category;

var markers:Array = getUniqueMarkers(categories);
var markersHolder:ViewStack = new ViewStack;
markersHolder.setStyle("verticalCenter",0);
markersHolder.setStyle("horizontalCenter",0);
markersHolder.width = 16;
markersHolder.height = 16;

for(var i:Number = 0;i<markers.length;i++){
var c:Canvas = createMarkerHolder(markers[i]);
markersHolder.addChild(c);
}
markersStack = markersHolder;
mx.controls.Alert.show("done");
markersHolder.selectedIndex = 5;
application.addChild(markersHolder);

var btn:Button = new Button;
btn.label = "add more";
btn.addEventListener(MouseEvent.CLICK, onMouseClick);
this.addChild(btn);
}
private function onMouseClick(ev:MouseEvent):void{
for(var s:int = 0;s<800;s++){
var f:Canvas = new Canvas;
f.width = 16;
f.height = 16;

var duplicate:ViewStack = new ViewStack;
for(var i:Number = 0;i<markersStack.numChildren;i++){
duplicate.addChild(markersStack.getChildAt(i));
}

duplicate.selectedIndex = 12;
f.addChild(duplicate);
f.x = Math.random() * 500;
f.y = Math.random() * 500;
this.addChild(f);
}
}
private function createMarkerHolder(markerURL:String):Canvas{
var container:Canvas = new Canvas;
container.horizontalScrollPolicy = "off";
container.verticalScrollPolicy = "off";
container.percentHeight = 100;
container.percentWidth = 100;
var loader:SWFLoader = new SWFLoader;
loader.percentWidth = 100;
loader.percentHeight = 100;
loader.load(markerURL);
loader.addEventListener(Event.COMPLETE, onMarkerLoaded);
var b:Button = new Button;
b.label = markerURL;
container.addChild(b);
container.addChild(loader);
return container;
}
private function onMarkerLoaded(ev:Event):void{
//Alert.show("loaded");
}
private function getUniqueMarkers(categories:ArrayCollection):Array {
var markers:Array = new Array;
for(var i:Number = 0;i<categories.length;i++){
if(categories[i].marker == "") continue;
var found:Boolean = false;
for(var m:int = 0;m<markers.length;m++){
if(markers[m] == categories[i].marker){
found = true;
}
}
if(!found)
markers.push(categories[i].marker);
}
return markers;
}
]]>
</mx:Script>

</mx:Application>

FredericCox
%Europe/Berlin %570 %2008, 13:41
Ik dacht dat bitmapData mss wel kon helpen maar de iconen moeten geschaald worden dus dat lijkt me ook geen optie (iconen zijn superkleine swf's geexporteerd uit illustrator)

TheDutch
%Europe/Berlin %207 %2008, 04:58
Die viewstack heb ik publiek gedeclareerd maar blijkbaar kan ik er alleen naar verwijzen en niet de viewstack dupliceren?
Ik snap deze zin niet echt :).
Die view stack is dan toch een class waar je instanties van kunt maken?

Een paar vragen:

Vraag 1: Komt het groter geheugenverbruik door het inladen of door de hoeveelheid iconen?
Vraag 2: Moeten de icons tijdens runtime schalen of enkel na het inladen eenmaal?
Vraag 3: Moeten de iconen dynamisch zijn of kan embedden een optie zijn?

FredericCox
%Europe/Berlin %611 %2008, 14:40
Ik ga je vragen in omgekeerde volgorde oplossen :)

Embedden was wat ik eerst deed en is dus geen optie. De iconen moeten schaalbaar zijn tijdens de runtime en het geheugengebruik zat blijkbaar in het feit dat ik de iconen ingeladen had via de marker.swf (dus in die SWF zat een functie om via flash het icoontje in te laden). Nu heb ik het icoon ingeladen via een SWFLoader in Flex en over de marker movieclip geplaatst en nu lijkt het opgelost. Geheugen gebruik valt op dit moment reuze mee.

Dus via de oudere methode was er ergens een lek denk ik

FredericCox
%Europe/Berlin %612 %2008, 14:42
Ik snap deze zin niet echt :).
Die view stack is dan toch een class waar je instanties van kunt maken?


Ik had een public var markerStack:ViewStack

Deze viewstack ging ik vullen met iconen en dan de viewstack dupliceren. Dat gaat dus niet meer dus probeerde ik het met een functie die via getChildAt de children uit de viewstack ging halen (zie code) maar dan verdwenen ze uit de markerStack (verplaatsen ipv kopieren). Maar bon, het is nu in elk geval opgelost maar een alternatief voor duplicateMovieClip zou leuk zijn

TheDutch
%Europe/Berlin %816 %2008, 19:36
Check hier: http://www.kirupa.com/forum/showpost.php?p=1939827&postcount=172

FredericCox
%Europe/Berlin %831 %2008, 19:57
Had ik geprobeerd maar de inhoud bleef wit

The only thing duplicateMovieClip does that this does not is copy dynamic drawing information. Currently, the graphics object in display objects cannot be duplicated so there is no way to obtain that information for duplicates in duplicateDisplayObject.

TheDutch
%Europe/Berlin %206 %2008, 04:57
Meer dan bovenstaande link kan je op dit moment nog niet krijgen. Het is waarschijnlijk wachten tot Adobe dit bij de DisplayObject class in zal bouwen :).