Flex - проблема с ResizeEvent.RESIZE - PullRequest
9 голосов
/ 22 января 2010

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

Ответы [ 4 ]

20 голосов
/ 26 января 2010

Вместо того, чтобы реагировать на ResizeEvent, который будет запускать каждый кадр во время изменения размера (т. Е. Если вы нажмете «развернуть» и потребуется 3 кадра для перерисовки компонента с widh / ehight = 0 до width / height = 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>

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

3 голосов
/ 22 января 2010

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

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

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

doResize(timerEvent):
    /* do actual resize processing */
    resizeEventReceived = false
1 голос
/ 16 августа 2011

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

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

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

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

1 голос
/ 23 января 2010

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

...