Журат М. - aframework
TRANSCRIPT
Автор: Журат М.И.(для внутреннего использования в ООО «Инним»)
AFramework
AFramework – это MVC(S) фреймворк с привкусом Flex фреймворка
Начало формирования: ~2009/2010 год
Текущая версия: 0.8
Визуальные компоненты;Сервисы (HTTP, Sockets);Загрузчики файлов;Модели;Таски (Tasks);Твины/эффекты;Менеджеры; Утилитные классы и компоненты.
Основные пакеты фреймворка:
«Черный ящик»
Черный ящик
Вход Выход
Новый код просто кишит ошибками;Высокие трудо- (и время) – затраты;Большое количество часто
используемых классов и компонентов;Использование общепринятых
паттернов программирования;Гибкая и простая архитектура;Повышение понимания чужого кода за
счет использования фреймворка.
Почему нужно использовать фреймворк ?
Сложный пользовательский интерфейс;Производительный код;Скорость разработки интерфейса;Широкий выбор базовых компонентов;Легкая расширяемость и
компануемость визуальных компонентов;
Поддержка скинирования, лейаутов и инвалидации.
Визуальная составляющая фреймворка
UIComponent – базовый класс всех
визуальных компонентов
Отложенная валидация на примере отложенной отрисовкиpublic function set backgroundAlpha(value:Number):void{ _backgroundAlpha = value; redraw();}public function set backgroundColor(value:uint):void{ _backgroundColor = value; redraw();}private function redraw():void{ var g:Graphics = this.graphics; g.clear(); g.beginFill(_backgroundColor, _backgroundAlpha); g.drawRect(0, 0, width, height);}
Отложенная валидация на примере отложенной отрисовки
var rect:Rect = new Rect();rect.backgroundColor = 0xFF0000;rect.backgroundAlpha = 0.7;rect.cornerRadius = 15;rect.width = 150;rect.height = 400;addChild(rect);
Отложенная валидация на примере отложенной отрисовкиpublic function set backgroundColor(value:uint):void{ _backgroundColor = value; _graphicsInvalid = true;}
public function redraw():void{ if (_graphicsInvalid) { var g:Graphics = this.graphics; g.clear(); g.beginFill(_backgroundColor, _backgroundAlpha); g.drawRect(0, 0, width, height); }}
Отложенная валидация на примере отложенной отрисовки
public function set backgroundColor(value:Number):void{ _backgroundColor = value; invalidateDisplayList();}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{ var g:Graphics = this.graphics; g.clear(); g.beginFill(_backgroundColor, _backgroundAlpha); g.drawRect(0, 0, width, height);}
#createChildren();#commitProperties() - #invalidateProperties();
#measure() - #invalidateSize();
#updateDisplayList() - #invalidateDisplayList().
UIComponent
#commitProperties() -
#invalidateProperties();
UIComponent
Пример валидации свойствoverride protected function commitProperties():void { if (_sourceInvalid) { if (_untrustedContent) { removeChild(_untrustedContent); _contentLoader .poolContent(_untrustedContent); _untrustedContent = null; } if (_sourceUrl && _sourceUrl.length > 0) _contentLoader.load(_sourceUrl, onContentLoadComplete); invalidateSize(); invalidateDisplayList(); _sourceInvalid = false; }}
#measure() - #invalidateSize();
UIComponent
UIComponent
#width/height#minWidth/#minHeight#maxWidth/#maxHeight#explicitWidth/#explicitHeight#measuredWidth/#measuredHeight
#setActualSize#contentWidth/#contentHeight
Пример расчета размеров компонента
override protected function measure():void{ if (iconDisplay) { var iconWidth:int = iconDisplay.width; var iconHeight:int = iconDisplay.height; }
if (labelDisplay) { var labelWidth:int = labelDisplay.width; var labelHeight:int = labelDisplay.height; }
_measuredWidth = Math.max(_background.width, iconWidth + labelWidth); _measuredHeight = Math.max(_background.height, iconHeight, labelDisplay.height);}
#updateDisplayList() - #invalidateDisplayList();
UIComponent
Пример отрисовки компонента
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void{ var g:Graphics = this.graphics; g.clear(); DrawUtil.drawCornerButton(g, background, 0, 0, unscaledWidth);
// иконка var ty:Number = (unscaledHeight - icon.height) * .5; DrawUtil.drawSprite(g, list, CommonWindowAsset.COIN_ICON, HPADDING - 1, ty);
// распологаем надпись _label.y = (unscaledHeight - _label.height) * .5 - .5; _label.x = HPADDING + icon.width + HGAP;}
#currentState - #onCurrentStateChanged
();
UIComponent
Возможные состояния обычной кнопки
Up state
Over state
Down state
Disabled state
Поддержка лейаутовОбрезка содержимого
Group
Автоизмерение размеров контейнера
Расположение дочерних элементов
Виртуализация
Лейауты (Layouts)
Пример лейаута
Пример 3D лейаута
Пример простого лейаута
public class AHorizontalLayout extends ALayoutBase{ override protected function measure ():void { for (var i:int = 0;i< target.numChildren;++i) { var child:DisplayObject = target.getChildAt(i); measuredWidth+= child.width; measuredHeight = Math.max( measuredHeight, child.height); } }}
Пример простого лейаута
override protected function updateDisplayList(w:Number, h:Number):void{ var tx:Number = 0;
for (var i:int = 0;i<target.numChildren;++i) { var child:DisplayObject = target.getChildAt(i);
child.y = 0; child.x = tx; tx+= child.width; }}
#clipAndEnableScrolling;#horizontalScrollPosition;#verticalScrollPosition;#contentWidth;#contentHeight.
Group#viewPort
Group#viewPort
horizontalScrollPosition,verticalScrollPosition
0,0
contentWidth
contentHeight
widthheight
0,0
width
height
Group#viewPort
IDataRenderer (DataRenderer / ItemRenderer);
IList (ArrayList / ArrayCollection / PagableArrayCollection);
Бесконечный список (Infinite list).
DataGroup
DataGroup
DataGroup
DataGroup
Виртуализация
ViewPort (видимая область)
Виртуальные элементы
Виртуальные элементы
Виртуализация
Высокий уровень стилизации;В качестве скина можно использовать
любой визуальный компонент;Низкая связанность;Возможность использовать скины
отдельно;Сокрытие сложности;Возможность изменять функциональность
компонента;Широкие возможности по отделению
бизнес-логики от визуальной мишуры.
SkinnableComponent
UserView
public class UserView extends ASkinnableComponent{ public var nameDisplay:IDisplayText; public var levelDisplay:IDisplayText; public var scoreDisplay:IDisplayText; public var avatarDisplay:AvatarBitmapImage;
//объявление остальных частей скина
UserView
override protected function registerSkinParts():void{ _skinParts = { nameDisplay : false, levelDisplay : false, scoreDisplay : false, avatarDisplay: false }}
UserView
override protected function partAdded(partName:String, instance:Object):void
{ super.partAdded(partName, instance);
if (instance === avatarDisplay) avatarDisplay.sourceUrl = _source.avatarUrl; else if (instance === nameDisplay) nameDisplay.text = _source.name; // else }
UserViewoverride protected function getCurrentSkinState():String{ if (!_source) return UserViewSkinStates.STATE_EMPTY; return _source.me ? UserViewSkinStates.STATE_CURRENT_USER : UserViewSkinStates.STATE_USER;}
UserViewoverride protected function commitProperties():void{ if (_sourceInvalid) { _source.addEventListener( AModelEvent.MODEL_CHANGED,
onSourceChanged);
if (nameDisplay) nameDisplay.text = _source.name;
if (levelDisplay) levelDisplay.text = _source.level;
if (avatarDisplay) avatarDisplay.sourceUrl = _source.avatarUrl;
if (scoreDisplay) scoreDisplay.text = _source.score;
}}
UserView
TitleWindow
Панель друзей
Окно выбора друга
Спасибо за внимание!