Управление Flex Tree - Как я могу ссылаться на иконки по URL? - PullRequest
2 голосов
/ 26 марта 2010

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

Я попытался просто использовать имя поля, содержащего URL-адрес, в качестве iconField в древовидном элементе управления, но, очевидно, когда гибкая инфраструктура видит строковое поле в качестве поля значка, она ищет свойство в mxml-файл, содержащий дерево с именем, совпадающим со строковым значением поля в элементе дерева (!?!). Поскольку в моих документах макета нет полей с именами, такими как "assets / well.png", это приводит к ошибке.

Мне нужно ссылаться на значки, используя URL-адрес изображений, а не путем встраивания, потому что клиент должен иметь возможность изменять изображение без перекомпиляции.

Ответы [ 2 ]

1 голос
/ 26 марта 2010
Функция

Tree setItemIcon (или свойство itemIcons) принимает два объекта Class в качестве параметров. Возможным решением будет добавить этот класс в ваш проект, а затем использовать следующий код для динамической загрузки ваших активов:

yourTree.itemIcons = {iconID: IconUtility.getClass(icon1, 'path/icon1.jpg'), iconID2: IconUtility.getClass(icon2, 'path/icon2.jpg')};


Edit:
Оригинальный пост о классе IconUtility: http://blog.benstucki.net/?p=42

0 голосов
/ 26 апреля 2011

Я попытался создать полный рабочий пример и хочу поделиться своим опытом здесь. Это мой тестовый код:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">

<mx:Script>
    <![CDATA[
    import mx.controls.listClasses.IListItemRenderer;

    private function tree_iconFunc(item:Object):Class
    {
        var iconClass:Class;
        var renderer:IListItemRenderer = myTree.itemToItemRenderer(item);
        switch (XML(item).@label.toString().charAt(0))
        {
            case "B":
                iconClass = IconUtility.getClass(renderer, 'http://onair.adobe.com/images/lynch.jpg', 16, 16);
                break;
            case "C":
                iconClass = IconUtility.getClass(renderer, 'http://onair.adobe.com/images/downey.jpg', 16, 16);
                break;
            case "K":
                iconClass = IconUtility.getClass(renderer, 'http://onair.adobe.com/images/mesh.jpg', 16, 16);
                break;
        }

        return iconClass;
    }
    ]]>
</mx:Script>

<mx:XML id="dp">
    <mlb>
        <league label="American League">
            <division label="East">
                <team label="Boston"/>
                <team label="New York"/>
                <team label="Toronto"/>
                <team label="Baltimore"/>
                <team label="Tampa Bay"/>
            </division>
            <division label="Central">
                <team label="Cleveland"/>
                <team label="Detroit"/>
                <team label="Minnesota"/>
                <team label="Chicago"/>
                <team label="Kansas City"/>
            </division>
            <division label="West">
                <team label="Los Angeles"/>
                <team label="Seattle"/>
                <team label="Oakland"/>
                <team label="Texas"/>
            </division>
        </league>
    </mlb>
</mx:XML>

<mx:Tree id="myTree"
         dataProvider="{dp.league}"
         labelField="@label"
         showRoot="true"
         iconFunction="tree_iconFunc"
         fontSize="12"
         width="500"
         height="400"/>

</mx:Application>

Он основан на этом примере: http://blog.flexexamples.com/2007/11/15/creating-a-custom-icon-function-on-a-flex-tree-control/

Это класс IconUtility, который я использую с ним:

package
{
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.geom.Matrix;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.utils.Dictionary;

import mx.containers.accordionClasses.AccordionHeader;
import mx.controls.tabBarClasses.Tab;
import mx.core.BitmapAsset;
import mx.core.UIComponent;

/**
 * Provides a workaround for using run-time loaded graphics in styles and properties which require a Class reference
 */
public class IconUtility extends BitmapAsset
{

    private static var dictionary:Dictionary;

    /**
     * Used to associate run-time graphics with a target
     * @param target A reference to the component associated with this icon
     * @param source A url to a JPG, PNG or GIF file you wish to be loaded and displayed
     * @param width Defines the width of the graphic when displayed
     * @param height Defines the height of the graphic when displayed
     * @return A reference to the IconUtility class which may be treated as a BitmapAsset
     * @example &lt;mx:Button id="button" icon="{IconUtility.getClass(button, 'http://www.yourdomain.com/images/test.jpg')}" /&gt;
     */
    public static function getClass( target:*, source:String, width:Number = NaN, height:Number = NaN ):Class {
        if(!dictionary) {
            dictionary = new Dictionary(false);
        }
        //if(source is String) {
            var loader:Loader = new Loader();
            loader.load(new URLRequest(source as String), new LoaderContext(true));
            //source = loader;
        //}
        dictionary[target] = { source:loader, width:width, height:height };

        return IconUtility;
    }

    /**
     * @private
     */
    public function IconUtility():void {
        addEventListener(Event.ADDED, addedHandler, false, 0, true)
    }

    private function addedHandler(event:Event):void {
        if(parent) {
            if(parent is AccordionHeader) {
                var header:AccordionHeader = parent as AccordionHeader;
                getData(header.data);
            } else if(parent is Tab) {
                var tab:Tab = parent as Tab;
                getData(tab.data);
            } else {
                getData(parent);
            }
        }
    }

    private function getData(object:Object):void {
        var data:Object = dictionary[object];
        if(data) {
            var source:Object = data.source;
            if(data.width > 0 && data.height > 0) {
                bitmapData = new BitmapData(data.width, data.height, true, 0x00FFFFFF);
            }
            if(source is Loader) {
                var loader:Loader = source as Loader;
                if(!loader.content) {
                    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
                } else {
                    displayLoader(loader);
                }
            }
        }
    }

    private function displayLoader( loader:Loader ):void {
        if(!bitmapData) {
            bitmapData = new BitmapData(loader.content.width, loader.content.height, true, 0x00FFFFFF);
        }
        bitmapData.draw(loader, new Matrix(bitmapData.width/loader.width, 0, 0, bitmapData.height/loader.height, 0, 0));
        if(parent is UIComponent) {
            var component:UIComponent = parent as UIComponent;
            component.invalidateSize();
        }
    }

    private function completeHandler(event:Event):void {
        if(event && event.target && event.target is LoaderInfo) {
            displayLoader(event.target.loader as Loader);
        }
    }

}
}

Это полная копия с Бена Стуки , за исключением аргумента target функции getClass, где я изменил тип с UIComponent на *, как рекомендовано в комментариях этот блог .

Осталось проблем:

  1. Мерцание значков: при открытии и / или закрытии веток происходит много мерцания. (Проверено на Firefox 3 и flashplayer 10.2)
  2. При загрузке значков текст в дереве «прыгает» вправо, если вы открываете ветку в первый раз
  3. В моей "настоящей" программе значок появляется только при наведении курсора мыши на узел дерева и исчезает при открытии другой ветви. Мне не удалось воспроизвести это в моей простой тестовой программе, но это явно проблема, поскольку другие также сообщили об этой проблеме.

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

...