Руководство по actionscript. часть 6, стр. 008

Не пытайтесь обращаться к загружаемому элементу до возникновения события Event. INIT.

Приемники, которые желают получать уведомления о возникновении события Event. INIT, должны быть зарегистрированы в объекте Loaderlnf о объекта элемента, а не в объекте Loader, над которым изначально был вызван метод load ( ). Объект Loaderlnfo— это отдельный объект, который представляет информацию о загруженном элементе. Любой экземпляр класса Loader предоставляет ссылку на объект Loaderlnfo своего загружаемого элемента через переменную экземпляра contentLoaderInf о. Таким образом, чтобы зарегистрировать приемник события для события Event. INIT некоторого элемента, мы используем следующий обобщенный код:

объект1_оас! ег. contentLoader Inf о. addEventLi stener (Event. INIT, приемникСобытияШ1Т);

Здесь объект1_оас! ег — это объект Loader, загружающий элемент, а приемникСобы-тияШП — ссылка на функцию, которая будет обрабатывать событие Event. INIT. После возникновения события Event. INIT благополучно обратиться к загруженному элементу можно через переменную content или метод getChildAt ( ) класса Loader, как показано ниже:

объект1оабег. content объект1оабег. getChi1dAt СО)

Обратите внимание на значение 0 в выражении getChildAt (0). Элемент является единственным ребенком объекта Loader, поэтому он находится на глубине с индексом 0.

Следующий код демонстрирует приемник события Event. INIT, который устанавливает позицию загруженного и проинициализированного элемента. Для демонстрации двух различных способов обращения к загруженному элементу этот код устанавливает горизонтальную позицию с помощью переменной content, а вертикальную позицию — с использованием выражения getChildAt (0).

private function initListener (e:Event):void { объектLoader. content. x = 50; oбъeктLoader. getCh^^(\^t(Q).y = 75;

}

В качестве альтернативы обратиться к загруженному элементу можно через объект Event, передаваемый в функцию-приемник события Event. INIT. Этот объект определяет переменную target, которая ссылается на объект Loaderlnfo элемента. Каждый объект Loaderlnfo ссылается на свой соответствующий элемент через переменную экземпляра content. Таким образом, внутри функции-приемника события Event. INIT ссылка на загруженный элемент может быть получена с помощью выражения o6beKTEvent. target. content. Например, следующий код устанавливает горизонтальной позиции загруженного элемента значение 100:

private function initListener (e;Event):void { e. target. content. x = 100;

}

При обращении к загруженным элементам следует помнить, что, поскольку элемент не добавляется в свой объект Loader до тех пор, пока процесс загрузки данного элемента не будет успешно завершен, вызов метода o6beKTLoader. getChi 1 dAt (0) до начала операции загрузки приведет к ошибке.

Руководство по actionscript. часть 6, стр. 009

Напомним, что элемент растрового изображения не добавляется в свой объект Loader до тех пор, пока не будет полностью загружен внешний файл. Элемент SWF-файла не добавляется в свой объект Loader до тех пор, пока не будут получены все элементы и классы для первого кадра, включая основной класс SWF-файла.

Более того, перед началом загрузки переменная content содержит значение nul 1. Это демонстрирует следующий код:

// Начинаем загрузку

var loader:Loader = new Loader( );

1oader.1oad(new URLRequest(«sunset. j pg»));

// Сразу же пытаемся обратиться к загружаемому элементу. // не дожидаясь завершения загрузки

traced oader. getChi 1 dAt (0)): // RangeError. Ошибка #2006:

// The supplied index is out of bounds. // (Указанный индекс выходит за пределы.)

tracedoader. content); // Выводит: null

Даже если операция загрузки началась, но элемент не был успешно загружен, обращение к переменной content или вызов метода getChildAt (0) приведет к следующей ошибке:

Error: Error #2099: The loading object is not sufficiently loaded to provide this information.

Руководство по actionscript. часть 6, стр. 010

На русском языке она будет выглядеть так: Загружаемый объект не был успешно загружен для предоставления данной информации.

Снова повторим: не пытайтесь обращаться к загружаемому элементу до момента возникновения события Event. INI Т. На самом деле обратное также верно: перед тем как обратиться к родительскому объекту Loader, код в основном классе загруженного SWF-файла должен дождаться возникновения события Event. INIT. В частности, код в конструкторе основного класса загруженного SWF-файла не имеет доступа к родительскому объекту Loader. С другой стороны, код, помещенный в первый кадр временной шкалы загруженного SWF-файла (в среде разработки Flash), может обращаться к родительскому объекту Loader (до возникновения события Event. INIT).

Воспользуемся новыми знаниями по обращению к элементам на примере класса SunsetViewer. В листинге 28.4 показано, как обращаться к загруженному файлу sunset. jpg из функции-приемника события Event. INIT. Эта функция отображает высоту, ширину и угол поворота загруженного изображения с помощью методик обращения к элементу, рассмотренных в данном разделе.

Листинг 28.4. Обращение к загруженному элементу

package { import flash. display.*; import flash. net. URLRequest; import flash. events.*;

public class SunsetViewer extends Sprite { private var loader:Loader;

public function SunsetViewer ( ) { loader = new Loader( );

// Регистрируем приемник для события Event. INIT

1 oader. contentLoaderlnfо. addEventLi stener(Event. INIT, initListener);

var urlRequest:URLRequest = new URLRequest(«sunset. jpg»); 1oader.1oad(urlRequest);

}

// Приемник вызывается при возникновении события Event. INIT private function initListener (e:Event):void {

// Обращаемся к элементу тремя различными способами

trace(1oader. content. wi dth);

trace(1oader. getChi1dAt(0).hei ght);

trace(e. target. content. rotati on);

}

S$4

Чтобы для загруженного элемента использовать методы и переменные класса Bitmap, MovieClip или основного класса SWF-файла, следуйте методикам, описанным далее в разд. «Проверка типов на этапе компиляции для динамически загружаемых элементов».

Руководство по actionscript. часть 6, стр. 011

Отображение загруженного элемента на экране

Как только элемент будет готов к использованию, он также будет готов к добавлению в список отображения для дальнейшего вывода на экран. Чтобы добавить загруженный элемент в список отображения, мы используем метод экземпляра addChild ( ) класса DisplayOb j ectContainer, как и при добавлении любого другого отображаемого объекта в список отображения. В листинге 28.5 представлен код, который добавляет объект Bitmap, представляющий файл sunset. j pg, в основной класс приложения SunsetViewer.

Листинг 28.5. Добавление элемента в список отображения

package { import flash. display.*; import flash. net. URLRequest; import flash. events.*;

public class SunsetViewer extends Sprite { private var loader;Loader;

public function SunsetViewer ( ) { loader = new Loader( );

loader. contentLoaderInfo. addEventListener(Event. INIT. initListener); var urlRequest:URLRequest = new URLRequest(«sunset. jpg»); loader. load(urlRequest);

}

private function initListener (e:Event):void { addChilddoader. content); // Добавляем объект Bitmap

// в объект SunsetViewer

}

}

}

Как показано в листинге 28.5, добавление объекта загруженного элемента в новый объект DisplayObjectContainer автоматически приводит к удалению этого элемента из его исходного родительского объекта Loader. В качестве примера добавим новый код в метод initListener ( ) из листинга 28.5. Этот код проверяет, сколько дочерних объектов имеет объект loader до и после добавления загруженного элемента (sunset, jpg) в объект SunsetViewer. Обратите внимание, что после перемещения элемента объект loader не имеет дочерних отображаемых объектов.

Руководство по actionscript. часть 6, стр. 012

Private function initListener (e:Event):void { tracedoader. numChildren); // Выводит: 1 (единственным ребенком

// является элемент)

addChi1d(1oader. content);

tracedoader. numChildren); // Выводит: 0 (поскольку элемент был

// перемещен)

}

Альтернативная методика вывода загруженного элемента на экран заключается в добавлении в список отображения объекта Loader этого элемента, а не объекта элемента.

Класс Loader сам по себе является потомком класса DisplayOb j ect, поэтому он непосредственно может быть добавлен в любой объект DisplayOb j ectContainer. Снова модифицируем метод initListener ( ) из листинга 28.5. На этот раз мы добавим объект loader непосредственно в объект SunsetViewer. В результате этой операции мы неявно делаем объект Bitmap, представляющий файл sunset. jpg, правнуком объекта SunsetViewer.

private function initListener (e:Event):void { addChilddoader); // Добавляем объект loader и его дочерний элемент // в список отображения

}

Объект Loader фактически может быть добавлен в список отображения до начала операции загрузки. Когда операция загрузки отображаемого элемента будет завершена, этот элемент автоматически добавится в объект Loader и, как следствие, в список отображения. Данная методика продемонстрирована в листинге 28.6. Код из этого листинга добавляет объект loader в список отображения до начала операции загрузки файла sunset. jpg. После того как экземпляр файла sunset. jpg будет создан и проинициализирован, он будет добавлен в объект loader и, поскольку объект loader уже находится в списке отображения, появится на экране. Таким образом, нет надобности в приемнике события Event. INIT.

Руководство по actionscript. часть 6, стр. 013

Листинг 28.6. Добавление объекта Loader в список отображения

package { import flash. display.*; import flash. net. URLRequest;

public class SunsetViewer extends Sprite { private var loader.-Loader;

public function SunsetViewer ( ) { loader = new Loader( ); addChilddoader);

var urlRequest:URLRequest = new URLRequest(«sunset. jpg»); loader. load(urlRequest);

}

}

}

Следовательно, самый простой из возможных способов загрузить отображаемый элемент и отобразить его на экране можно представить следующим кодом:

var loader:Loader = new Loader( ); addChilddoader);

1 oader. 1 oad(new URLRequest (адресиШЭлемента));

Три предыдущие строки кода подходят для многих простых ситуаций, однако в тех случаях, когда управление загруженным элементом должно осуществляться независимо от его объекта Loader или когда длительность паузы перед отображением загруженного элемента должна определяться вручную, более подходящим является код, который был представлен ранее в листинге 28.5.

Руководство по actionscript. часть 6, стр. 014

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

Отображение хода загрузки

Чтобы отобразить ход загрузки элемента, мы должны выполнить четыре следующих обобщенных шага.

1. Перед загрузкой элемента создать графический индикатор хода загрузки (например, текстовое поле или «индикатор загрузки»).

2. После начала загрузки добавить индикатор хода выполнения в список отображения.

3. По мере загрузки элемента обновлять состояние индикатора хода выполнения (по большому счету, это делается для удобства пользователя).

4. Когда загрузка будет завершена, удалить индикатор хода выполнения с экрана.

Посмотрим, как применить описанные шаги на практике, добавив простой индикатор хода выполнения, который реализован на базе текстового поля, в наш класс SunsetViewer.

Начнем с создания в классе SunsetViewer новой переменной экземпляра progressOutput, которая ссылается на обычный объект TextField. Текстовое поле progressOutput будет отображать информацию о ходе загрузки, private var progressOutput:TextField;

Далее мы создадим в классе SunsetViewer два новых метода: createPro gresslndicator ( ) и load ( ). Первый метод создает объект TextField progressOutput. Мы будем вызывать метод createProgressIndicator ( ) из конструктора класса SunsetViewer. Рассмотрим этот код:

private function createProgressIndicator ( ):void { progressOutput = new TextField( ); progressOutput. autoSi ze = TextFi eldAutoSi ze. LEFT; progressOutput. border = true; progressOutput. background = true; progressOutput. selectable = false; progressOutput. text = «LOADING…»;

}

Второй метод добавляет объект progre s sOutpu t в список отображения и начинает загрузку элемента. Всякий раз, когда с помощью метода load ( ) инициируется загрузка, объект progressOutput помещается на экран; всякий раз, когда загрузка завершается, объект progressOutput удаляется с экрана. Данная архитектура позволяет классу SunsetViewer повторно использовать один и тот же объект TextField для отображения информации о ходе загрузки. Рассмотрим код для метода load ( ):

private function load (urlRequest:URLRequest):void { // Начинаем загрузку loader. load(urlRequest);

// Если объект progressOutput еще не является потомком данного объекта… if (lcontains(progressOutput)) {

// …добавляем его

addChild(progressOutput);

}

}

В процессе загрузки мы ожидаем возникновения события ProgressEvent. PROGRESS, которое свидетельствует о появлении новой порции данных файла sunset. jpg и предоставляет самую последнюю информацию о ходе загрузки. Всякий раз, когда возникает событие ProgressEvent. PROGRESS, мы обновляем объект progressOutput. Получателем данного события является объект Loaderlnfo нашего загружаемого элемента. Как мы уже знаем, обратиться к объекту Loaderlnfo элемента можно через переменную экземпляра contentLoader Inf о класса Loader. Таким образом, чтобы зарегистрировать приемник для получения уведомлений о возникновении события ProgressEvent. PROGRESS, мы используем следующий код:

1oader. contentLoaderInfо. addEventLi stener(ProgressEvent. PROGRESS,

progressListener);

В приведенном коде progressListener— это ссылка на функцию, которую мы хотим выполнять при возникновении события ProgressEvent. PROGRESS. В функцию progressListener передается объект ProgressEvent, переменные которого содержат следующую информацию:

? размер файла загружаемого элемента (bytesTotal);

? количество байтов, полученных до настоящего момента (bytesLoaded).

Руководство по actionscript. часть 6, стр. 015

Следующий код демонстрирует функцию progressListener для нашего класса SunsetViewer. Обратите внимание, как эта функция получает информацию

0 ходе выполнения загрузки из объекта ProgressEvent е:

private function progressListener (e:ProgressEvent);void { // Обновляем индикатор хода выполнения. 1 Кбайт равен 1024 байт, // поэтому делим результат на 1024, чтобы преобразовать его в килобайты. progressOutput. text = «LOADING: «

+ Math. floor(е. bytesLoaded / 1024)

+ 7″ + Math, fl oor (e. bytesTotal / 1024) + » KB»;

}

Когда элемент будет загружен полностью, среда Flash выполнит диспетчеризацию события Event. COMPLETE, получателем которого является объект Loaderlnfo элемента. При возникновении события Event. COMPLETE мы можем удалить индикатор хода выполнения (progressOutput) из списка отображения.

Чтобы зарегистрировать приемник для событий Event. COMPLETE в объекте Loaderlnfo нашего загружаемого элемента, мы используем следующий код:

1 oader. contentLoaderInfо. addEventLi stener(Event. COMPLETE,

completeListener);

Здесь completeListener — это ссылка на функцию, которую мы хотим выполнять при возникновении события Event. COMPLETE. Следующий код демонстрирует функцию completeListener. Ее роль заключается в простом удалении объекта progressOutput из списка отображения.

Руководство по actionscript. часть 6, стр. 016

Private function completeListener (e:Event):void { • // Удаляем индикатор хода выполнения removeChild(progressOutput);

}

Наконец, чтобы облегчить повторное использование кода и упростить его чтение, мы переместим наш код для создания объекта Loader и код, регистрирующий приемники событий, в новый метод createLoader ( ), представленный ниже. Обратите внимание, что код в этом методе регистрирует приемники не только для событий ProgressEvent. PROGRESS и Event. COMPLETE, но и для события Event. INIT, которое было рассмотрено ранее в подразд. «Обращение к загруженному элементу». Как и раньше, мы помещаем наш загруженный элемент в список отображения при возникновении события Event. INIT. Рассмотрим код для метода createLoader ( ):

private function createLoader ( ):void { // Создаем объект Loader loader = new Loader( );

// Регистрируем приемники для событий

1oader. contentLoaderInfо. addEventLi stener(ProgressEvent. PROGRESS, progressListener);

1oader. contentLoaderlnfо. addEventLi stener(Event. COMPLETE, completeLi stener); 1oader. contentLoaderlnfo. addEventLi stener(Event. INIT, i nitLi stener);

}

Код, который удаляет индикатор хода выполнения из списка отображения (в нашем примере он представлен методом completeListener ( ) ), должен всегда использовать событие Event. COMPLETE вместо Event. INIT. Не путайте эти два события. Событие Event. INIT выражает качественное состояние «готовности элемента», а событие Event. COMPLETE — количественное состояние завершения загрузки. Событие Event. INIT обозначает, что элемент готов к использованию, даже если — в случае SWF-файла — загрузка еще продолжается. В отличие от этого, событие Event. COMPLETE свидетельствует о получении всех байтов файла, содержащего элемент.

^ I Используйте событие Event. INIT, чтобы определить момент, когда можно благополучно А щ обращаться к элементу. Применяйте событие Event. COMPLETE, чтобы определить момент З?-’ завершения операции загрузки.

Руководство по actionscript. часть 6, стр. 017

Поскольку некоторые типы элементов могут быть проинициализированы до того, как будут полностью загружены, событие Event. INIT всегда возникает перед событием Event. COMPLETE. Предположим, что мы загружаем SWF-файл, представляющий анимацию из 2000 кадров. Когда первый кадр будет загружен и проинициализирован, возникнет событие Event. INIT. В этот момент мы добавляем анимацию в список отображения и разрешаем начать ее воспроизведение, хотя загрузка SWF-файла все еще продолжается. По мере загрузки SWF-файла индикатор будет представлять ход выполнения данной операции. Когда загрузка SWF-файла будет завершена, возникнет событие Event. COMPLETE и мы удалим индикатор загрузки с экрана.

В листинге 28.7 снова представлен наш класс SunsetViewer, но на этот раз он включает код для отображения индикатора хода загрузки, рассмотренный в текущем разделе.

Листинг 28.7. Отображение хода загрузки

package { import flash. display.*; import flash. net. URLRequest; import flash. events.* import flash. text.*;

public class SunsetViewer extends Sprite { private var loader:Loader; // Загрузчик элемента

private var progressOutput:TextField; // Поле, в котором будет

// отображаться ход загрузки

// Конструктор

public function SunsetViewer ( ) { // Создаем объект Loader и регистрируем приемники событий createLoader( );

// Создаем индикатор хода выполнения createProgressIndicator( );

// Начинаем загрузку

load(new URLRequestC»sunset. jpg»));

}

private function createLoader ( ):void { // Создаем объект Loader loader = new Loader( );

// Регистрируем приемники для событий

1 oader. contentLoaderInfo. addEventLi stener(ProgressEvent. PROGRESS, progressListener);

1 oader. contentLoaderInfо. addEventLi stener(Event. COMPLETE, completeLi stener); 1 oader. contentLoaderlnfо. addEventLi stener(Event. INIT, i ni tLi stener);

}

private function createProgressIndicator ( ):void { progressOutput = new TextField( ); progressOutput. autoSi ze = TextFi eldAutoSi ze. LEFT; progressOutput. border = true; progressOutput. background = true; progressOutput. selectable = false; progressOutput. text = «LOADING…»;

}

private function load (urlRequest:URLRequest):void { loader. load(urlRequest); if (lcontains(progressOutput)) {

addChild(progressOutput):

}

}

// Приемник вызывается, когда появляются данные private function progressListener (е:ProgressEvent):void { // Обновляем индикатор хода выполнения. progressOutput. text = «LOADING: «

+ Math. floor(e. bytesLoaded / 1024)

+ «/» + Math. floor(e. bytesTotal / 1024) + » KB»;

}

private function initListener (e:Event):void { addChilddoader. content); // Добавляем загруженный элемент в список

// отображения

}

// Приемник вызывается, когда загрузка элемента полностью завершена private function completeListener (e:Event):void {

// Удаляем индикатор хода выполнения.



Полезные ссылки
Случайные записи
  • 11.03.2011">Руководство по actionscript. часть 4, стр. 009
  • 17.03.2011">Руководство по actionscript. часть 2, стр. 141
  • 09.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.163
  • 03.03.2011">Руководство по actionscript. часть 5, стр. 070
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 050
  • 28.02.2011">Руководство по actionscript. часть 6, стр. 006
  • 18.10.2019">Игровой автомат Always Hot в Azino
  • 27.02.2011">Руководство по actionscript. часть 6, стр. 037
  • 13.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.85
  • 04.03.2011">Руководство по actionscript. часть 5, стр. 044
  • 23.01.2011">Руководство по actionscript. часть 1, стр. 090
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.85
  • 12.04.2011">Делаем загар при помощи Photoshop
  • 23.02.2011">Руководство по actionscript. часть 7, стр. 026
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.83
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...