Search

Rss Posts

Rss Comments

Login

 

Deferred creation of ViewStack children

Сен 16

Задача: ускорить процесс запуска приложения, путем создания только нужных контейнеров в multiview контейнерах (ViewStack, TabNavigator, Accordion).

По-умолчанию creationPolicy="auto", но иногда хочется поставить им вообще "none" и взять под свой контроль процесс создания чилдов.

Решение: создавать дочерние контейнеры из их декспритора.

Код:

<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical"
	creationComplete="{bBar.selectedIndex = -1}">

	<mx:Script>
		<![CDATA[
			import mx.core.UIComponentDescriptor;
			import mx.formatters.SwitchSymbolFormatter;
			import mx.events.ItemClickEvent;
			import mx.controls.Alert;

			public var c : int = 0;

			private function println (str : String) : void
			{
				output.text += String(c++) + ": " + str + "\n";
			}

			private function onItemClick (event : ItemClickEvent) : void
			{
				var childDescriptor : UIComponentDescriptor = vstack.childDescriptors[event.index];
				var selectedChild : * = vstack.getChildByName(childDescriptor.id);

				if (selectedChild == null)
				{
					selectedChild = vstack.createComponentFromDescriptor(childDescriptor, false);
					vstack.selectedChild = selectedChild;
					vstack.validateNow();
				}
				else
				{
					vstack.selectedChild = selectedChild;
				}
			}
		]]>
	</mx:Script>

	<mx:ToggleButtonBar
		id="bBar"
		itemClick="onItemClick(event)">
		<mx:dataProvider>
			<mx:String>Canvas 1</mx:String>
			<mx:String>Canvas 2</mx:String>
			<mx:String>Canvas 3</mx:String>
		</mx:dataProvider>
	</mx:ToggleButtonBar>

	<mx:ViewStack
		id="vstack"
		width="400"
		height="250"
		creationPolicy="none">

		<mx:Canvas
			id="c1"
			label="Canvas 1"
			backgroundColor="#CC9955"
			initialize="println('canvas 1 inited')"
			creationComplete="println('canvas 1 created')"
			show="println('Show Canvas #1')">
			<mx:Label
				text="Canvas #1" />
			<mx:Button
				id="b1"
				top="20"
				label="button 1" />
		</mx:Canvas>

		<mx:Canvas
			id="c2"
			label="Canvas 2"
			backgroundColor="#99CC55"
			initialize="println('canvas 2 inited')"
			creationComplete="println('canvas 2 created')"
			show="println('Show Canvas #2');">
			<mx:Label
				text="Canvas #2" />
			<mx:Button
				id="b2"
				top="20"
				label="button 2" />
		</mx:Canvas>

		<mx:Canvas
			id="c3"
			label="Canvas 3"
			backgroundColor="#9955CC"
			initialize="println('canvas 3 inited')"
			creationComplete="println('canvas 3 created')"
			show="println('Show Canvas #3')">
			<mx:Label
				text="Canvas #3" />
			<mx:Button
				id="b3"
				top="20"
				label="button 3" />
		</mx:Canvas>

	</mx:ViewStack>

	<mx:TextArea
		id="output"
		width="400"
		height="250"
		editable="false" />

</mx:Application>

Можно заметить, что самый первый показанный контейнер не диспатчит ивент show - так работает ViewStack…

О creationPolicy (none, auto, all, queued): LiveDocs: About the creationPolicy property

Во Флексе есть два вида контейнеров: singleview и multiview.

Для multiview:
- none - не создававть ничего;
- all - создать все чилды (и их чилды рекурсивно). очень жестко;
- auto - создать только первоначальный контейнер (и его чилды), т.е. тот что указан в selectedIndex/selectedChild или самый первый если не указано. остальные контейнеры будут инстатиированы но не инициированы, при этом их чилды не будут созданы, естественно события initialize и creationComplete не опубликуются.

Для singleview контейнера (VBox, HBox, Canvas) значение all/auto и none - соответственно создавать автоматически чилды (и чилды их чилдов - рекурсивно) или нет. В данном случае all и auto равнозначны. Значение queued - позволяет управлять очередностью создания с помощью тега creationIndex. Вот небольшой пример для иллюстрации:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Panel
    	creationPolicy="queued"
    	initialize="{trace('panel 1 inited')}"
    	creationComplete="{trace('panel 1 created')}">
        <mx:Button
        	label="Button 1.1"
        	initialize="{trace('button 1.1 inited')}"
        	creationComplete="{trace('button 1.1 created')}"/>
        <mx:Button
        	label="Button 1.2"
        	initialize="{trace('button 1.2 inited')}"
        	creationComplete="{trace('button 1.2 created')}" />
    </mx:Panel>

    <mx:Panel
    	creationPolicy="queued"
    	creationIndex="0"
    	initialize="{trace('panel 2 inited')}"
    	creationComplete="{trace('panel 2 created')}">
        <mx:Button
        	label="Button 2.1"
        	initialize="{trace('button 2.1 inited')}"
        	creationComplete="{trace('button 2.1 created')}"/>
        <mx:Button
        	label="Button 2.2"
        	initialize="{trace('button 2.2 inited')}"
        	creationComplete="{trace('button 2.2 created')}" />
    </mx:Panel>

    <mx:Panel
    	creationPolicy="queued"
    	initialize="{trace('panel 3 inited')}"
    	creationComplete="{trace('panel 3 created')}">
        <mx:Button
        	label="Button 3.1"
        	initialize="{trace('button 3.1 inited')}"
        	creationComplete="{trace('button 3.1 created')}" />
        <mx:Button
        	label="Button 3.2"
        	initialize="{trace('button 3.2 inited')}"
        	creationComplete="{trace('button 3.2 created')}" />
    </mx:Panel>
</mx:Application>

Вывод программы:
button 2.1 inited
button 2.2 inited
panel 2 inited
button 2.1 created
button 2.2 created
panel 2 created
button 1.1 inited
button 1.2 inited
panel 1 inited
button 1.1 created
button 1.2 created
panel 1 created
button 3.1 inited
button 3.2 inited
panel 3 inited
button 3.1 created
button 3.2 created
panel 3 created

Post a comment

You must be logged in to post a comment.