2010-01-22 3 views
9

У меня небольшая проблема с моим событием изменения размера ... Я сам создал компонент, и этот компонент в каждом событии изменения размера выполняет сложный метод. Вот проблема: когда я максимизирую или восстанавливаю свое окно, это событие вызывается несколько раз за очень короткий промежуток времени, не позволяя мне достаточно времени, чтобы мой метод запускался полностью, прежде чем начнется другой ... Я хотел бы знать если в конце каждого изменения размера будет выполняться только этот метод. ThanksFlex - проблема с ResizeEvent.RESIZE

ответ

20

Вместо того чтобы реагировать на ResizeEvent, который будет срабатывать каждый кадр во время изменения размера (то есть, если вы нажмете максимального и занимает 3 кадров для компонента перерисовывать из widh/ehight = 0 по ширине/высоте = MaxValue), то событие изменения размера будет срабатывать три раза, вы можете «наблюдать» за свойствами ширины и высоты.

var widthWatch:ChangeWatcher = ChangeWatcher.watch(this, 'widht', resizeHandler) 
var heightWatch:ChangeWatcher = ChangeWatcher.watch(this, 'height' resizeHandler) 

это будет, по сути, посмотреть свойства, подобные привязки данных и выполнить свой resizeHandler всякий раз, когда ширина или высота изменения. Это имеет небольшой недостаток в том, что вы дважды стреляете в обработчик, если одновременно изменяются ширина и высота, но это может быть решено с помощью третьей функции, которая выполняет работу, которая вызывается обработчиками, если это не расписание для вызова , Код:

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete(event)"> 
<mx:Script> 
<![CDATA[ 
    import mx.binding.utils.ChangeWatcher; 

    private var widthWatch:ChangeWatcher; 
    private var heightWatch:ChangeWatcher; 
    private var resizeExecuting:Boolean = false; 

    private function onCreationComplete(event:Event):void 
    { 
    widthWatch = ChangeWatcher.watch(this,'width',onSizeChange); 
    heightWatch = ChangeWatcher.watch(this,'height',onSizeChange); 
    } 

    private function onSizeChange(event:Event):void 
    { 
    if(!resizeExecuting) 
    callLater(handleResize); 
    resizeExecuting = true; 
    } 

    private function handleResize():void 
    { 
    //do expensive work here 
    resizeExecuting = false; 
    } 

    private function stopWatching() 
    { 
    //invoke this to stop watching the properties and prevent the handleResize method from executing 
    widthWatch.unwatch(); 
    heightWatch.unwatch(); 
    } 

]]> 
</mx:Script> 
</mx:Application> 

Я предпочитаю метод изменения наблюдател, потому что он срабатывает после того, как ширина и высота изменились, в отличие от Wich изменения размера событие пожаров, прежде чем свойства ширина и высота correclty обновляются.

+0

это действительно классный материал, спасибо, что поделились этим! – D3vtr0n

+1

в качестве дополнения к этому, так как я много испытываю эту проблему для наших компонентов диаграмм в Dedoose, разбив вашу сложную операцию с greenthreading (http://code.google.com/p/greenthreads/). Держите ручку в текущем GreenThread, и если она не завершена, вы можете остановить ее вычисление в середине, чтобы перезапустить. Это позволяет отличную адаптацию пользовательского интерфейса и одновременное решение сложных вычислений при изменении размера. – JTtheGeek

+0

Это было действительно полезно, спасибо. – ggkmath

3

Вы хотите объединить события изменения размера в одно событие. Дэвид Колетта кратко рассказал о объединении событий в this presentation, но я не помню, описал ли он, как он это сделал.

Вы можете сделать это несколькими способами, один из которых я буду макет в псевдокоде ниже:

resizeHandler(resizeEvent): 
    if (resizeEventReceived) 
     return 
    resizeEventReceived = true 
    Timer.startIn(30 /*ms*/).withHandler(doResize) 

doResize(timerEvent): 
    /* do actual resize processing */ 
    resizeEventReceived = false 
1

Это звучит для меня, как вы делаете что-то в обработчик событий, который вызывает новый ResizeEvent.RESIZE, который будет запущен. Поскольку ActionScript работает в одном потоке, никакой независимый источник не может отправить это событие во время работы вашего обработчика, если вы его каким-то образом не запускаете.

1

Я хотел бы отметить, что прогибается имеет полный жизненный цикл компонентов, которые могут помочь вам:

Попробуйте это:

  1. непосредственно не рассчитать изменения экрана, но сделать это в методе updateDisplayList ,
  2. При получении ResizeEvent, только вызов метода invalidateDisplayList(), который устанавливает рамки флаг, который будет инициировать выполнение updateDisplayList()

Вы можете прочитать больше о жизненном цикле Flex3 компонентов здесь: http://www.dlgsoftware.com/primers/Primer_on_Flex3_Component_Lifecycle.htm