带列表的Spark Mobile Callout无法正确定位/调整大小

时间:2013-07-21 15:48:11

标签: flex mobile air flex4 flex-spark

我创建了一个带有List的简单Callout。 像这样:

<s:Callout xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" 
       autoLayout="true" >
<fx:Declarations>
    <!-- Platzieren Sie nichtvisuelle Elemente (z. B. Dienste, Wertobjekte) hier -->
</fx:Declarations>

<fx:Script>
    <![CDATA[
        import com.skill.flextensions.factories.StyledClassFactory;

        import mx.collections.IList;

        import spark.components.IconItemRenderer;
        import spark.components.List;
        import spark.events.IndexChangeEvent;
        import spark.layouts.HorizontalAlign;
        import spark.layouts.VerticalLayout;

        private var _list:List; 
        //
        // PUBLIC PROPERTIES
        //
        private var _dataProvider:IList;
        private var _dataProviderChanged:Boolean = false;
        public function get dataProvider():IList
        {
            return _dataProvider;
        }

        public function set dataProvider(value:IList):void
        {
            _dataProvider = value;
            _dataProviderChanged = true;
            this.invalidateProperties();
        }

        private var _itemRenderer:IFactory;
        private var _itemRendererChanged:Boolean = false;
        public function get itemRenderer():IFactory
        {
            return _itemRenderer;
        }
        public function set itemRenderer(value:IFactory):void
        {
            _itemRenderer = value;
            _itemRendererChanged = true;
            this.invalidateProperties();
        }
        //          
        // @ SUPER
        //
        override protected function commitProperties():void
        {
            super.commitProperties();

            if(_dataProviderChanged)
            {
                _dataProviderChanged = false;
                _list.dataProvider = _dataProvider;
                // TODO
                // we have to remeasure, after dataprovider updated
                // unfortunately, this doesn't work:
                /*
                _list.invalidateSize();
                _list.invalidateDisplayList();
                _list.validateNow();
                invalidateSize();
                invalidateDisplayList();
                validateNow();
                */
                // so we will have to find a workaround for this situation.
            }

            if(_itemRendererChanged)
            {
                _itemRendererChanged= false;
                _list.itemRenderer = getItemRenderer();
            }
        }

        override protected function createChildren():void
        {
            _list = new List;
            _list.top = _list.bottom = 0;                   
            _list.itemRenderer = getItemRenderer();
            _list.addEventListener( IndexChangeEvent.CHANGE , onChange , false , 0 , true );

            var l:VerticalLayout = new VerticalLayout;
            l.gap = 0;
            l.requestedMinRowCount = 0;
            l.horizontalAlign = HorizontalAlign.CONTENT_JUSTIFY;
            _list.layout = l;

            this.addElement( _list );
        }
        //
        // @ LIST
        //
        protected function onChange(e:IndexChangeEvent):void
        {
            var obj:Object = _list.selectedItem;
            this.removeAllElements();
            _list = null;
            this.close(true , obj);
        }

        private function getItemRenderer():IFactory
        {
            if( ! _itemRenderer )
            {
                var fac:StyledClassFactory = new StyledClassFactory( IconItemRenderer );

                var props:Object = new Object;
                props.messageField = "message";
                props.labelField = "";
                props.styleName = "itemName";
                props.iconField = "icon";

                var styles:Object = new Object;
                styles.messageStyleName = "itemHeadline";

                fac.properties = props;
                fac.styles = styles;

                return fac;
            }
            return _itemRenderer;
        }

    ]]>
</fx:Script>

这里的问题是,我的标注不能正确测量。将dataProvider添加到List时,它总是将List的大小调整为第一个项目。当List发生某些用户交互时,它会突然正确调整大小(调整到最大的项目)。

不幸的是,CallOut-Position没有改变,导致错误的Callout,有时甚至是屏幕的一半。

所以我想确保,在打开标注之前,List的大小合适。

我该怎么做?很多你的意见。

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。我确信有一种更优雅的方式可以做到,但这是我的解决方案。

  1. 侦听Callout FlexEvent.CREATION_COMPLETE:

    <s:Callout xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" 
       autoLayout="true"
       creationComplete="init()">
    
  2. 强制标注重做其布局/尺寸:

    function init():void
    {
        validateNow();
        updatePopUpPosition();
    }
    
  3. 在我的应用程序中,我处理列表数据的数量与您的处理方式略有不同,因此您可能需要在设置数据后调用init()。