AS3: определение, когда отображаемый объект, наконец, отображается - PullRequest
0 голосов
/ 08 апреля 2011

Я ищу, чтобы определить окончательное событие или место, где можно было бы определить, что изображение или UIComponent было предоставлено пользователю.Мне нужно знать, когда он был отображен и, следовательно, предположил, что он не скрыт или находится в глупом месте, видимом для пользователя.

В документации по событию UpdateComplete говорится:

Это последняя возможность изменить компонент перед его отображением.Все свойства были зафиксированы, а компонент был измерен и размечен.

Переопределение dispatchEvent на изображении показывает, что событие UpdateComplete является последним, которое отправляется после обновления свойства .source.,Точка останова и обход кода после этого события показывают, что LayoutManager, похоже, завершает свои действия до отображения изображения.

Я наблюдал за dispatchEvent on и updateDisplayList на контейнере canvas и без кубиков.

Я предполагаю, что есть какой-то более высокий (более низкий) объект, который я мог бы расширить или прослушать, что дало бы мне эту последнюю часть информации.

Помогите пожалуйста.

====================================================

РЕДАКТИРОВАТЬ: ДОБАВЛЕНИЕ КОДА ОБРАЗЕЦ ТЕСТА APP

===============================================

NoisyImageTest.mxml - тестовое приложение для просмотра цикла событий.Если вы остановитесь на строке 22, вы увидите последнее событие updateComplete, но изображение еще не отображается.Проходя оттуда код, он выходит из потока после LayoutManager, но все еще не обновил экран.Я предполагаю, что есть момент, когда systemManager или stage или какой-то другой элемент могут сказать, что он нарисовал изображение.это то, что я ищу.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:local="*">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            private var imagePointer : NoisyImage;

            private function onImageLoadClick( event : MouseEvent ) : void
            {
                //start loading the image
                canvasTarget.removeAllChildren();
                imagePointer = new NoisyImage();
                imagePointer.addEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateComplete);
                canvasTarget.addChild( imagePointer );
                imagePointer.source = 'http://helios.gsfc.nasa.gov/image_euv_press.jpg';
            }  

            private function onImageLoadClick2( event : MouseEvent ) : void
            {
                if ( imagePointer )
                {
                    imagePointer.source = 'http://helios.gsfc.nasa.gov/30dor_qdw_big.gif';
                }
            }

            private function onUpdateComplete( event : FlexEvent ) : void
            {
                trace('percentLoaded ' + ( event.target as NoisyImage ).percentLoaded );
                trace('bytesLoaded ' + ( event.target as NoisyImage ).bytesLoaded );
                trace('content ' + ( event.target as NoisyImage ).content );
                if ( event.target.source )
                {
                    trace('onUpdateComplete has valid source.');
                    if ( event.target.width )
                    {
                        trace('onUpdateComplete has valid width.');                    
                    }
                }

            }             
        ]]>
    </fx:Script>
    <local:NoisyCanvas id="canvasTarget" width="500" height="400" horizontalCenter="0" />
    <mx:Button label="load image" click="onImageLoadClick(event)" horizontalCenter="0" />
    <mx:Button label="sticth source to image2" click="onImageLoadClick2(event)" horizontalCenter="0" />
</s:Application>

NoisyCanvas.as - это холст, в который будет помещен noisyImage, который обеспечивает все трассировки отправленных событий

package
{
    import flash.events.Event;

    import mx.containers.Canvas;

    public class NoisyCanvas extends Canvas
    {
        public function NoisyCanvas()
        {
            super();
        }

        override public function dispatchEvent(event:Event):Boolean
        {
            trace( 'c dispatchEvent: ' + event );
            return super.dispatchEvent(event);
        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            trace( 'c updateDisplayList: ' + unscaledWidth + ' ' + unscaledHeight );
            super.updateDisplayList(unscaledWidth, unscaledHeight);
        }

        override protected function childrenCreated():void
        {
            trace( 'c childrenCreated' );
            super.childrenCreated();
        }        
    }
}

NoisyImage.as - это изображение, которое обеспечиваетвсе следы отправленных событий

package
{
    import flash.events.Event;

    import mx.controls.Image;

    public class NoisyImage extends Image
    {
        public function NoisyImage()
        {
            super();
        }

        override public function dispatchEvent(event:Event):Boolean
        {
            trace( 'i dispatchEvent: ' + event );
            return super.dispatchEvent(event);
        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            super.updateDisplayList(unscaledWidth, unscaledHeight);
            trace( 'i updateDisplayList: ' + unscaledWidth + ' ' + unscaledHeight );
        }        
    }        
}

1 Ответ

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

хорошо .... Я думал, что у меня есть решение. К сожалению, я действительно не знаю flex, но могу предоставить созданные мной классы Blitting.

Я надеюсь, что вы можете использовать эти (или, по крайней мере, идеи воплощены), чтобы найти решение, которое поможет вам. Я верю, что это возможно - я просто недостаточно хорошо знаю объекты Flex, чтобы реализовать их.

Также обратите внимание, что эти классы были созданы для игры, которую я пытаюсь создать, поэтому не стесняйтесь обрезать все, что вам не нужно. Есть также несколько незавершенных методов. Это немного небрежно. : - \

// Oh, and, please ignore my code comments, I tend to talk to myself.

Класс BLOB - это базовый объект для многих из этих классов, состоящий из объекта bitmapData . Прямоугольные и точечные переменные были для моих copyPixels операций; возможно, вы сможете извлечь эти значения из ваших объектов.

package com.lunchmeat317.blitter
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    /**
     * ...
     * @author lunchmeat317
     */
    public class BLOB
    // BLOB stands for BLit OBject.
    {
        // These are the core variables of this class. Debating whether to make these
        // internal or protected. Protected is logical, but are getters slower for
        // parsing?

        internal var data:BitmapData;
        internal var rect:Rectangle;
        internal var point:Point;

        // To be used with scrollrect in order to animate frames. Frameoffset...shit.
        // Do I pull these values from rect.width and rect.height? Is this necessary?
        // Maybe I should just make these booleans? Perhaps these value can be the
        // quotient of the rect dims from the bitmap dims? No idea. (That could help
        // with wrapping.)
        private var frameoffset:uint;

        // Variable that determines whether to blit this object or not. Blitting engine
        // will check this condition for each object it blits. True by default.
        private var visible:Boolean;

        public function BLOB(width:uint, height:uint, x_pos:int, y_pos:int, x_rectpos:uint, y_rectpos:uint, image:BitmapData)
        {
            data = image;
            rect = new Rectangle(x_rectpos, y_rectpos, width, height);
            point = new Point(x_pos, y_pos);

            visible = true;

            data.lock();
        }

        public function setVisibleState(value:Boolean):void
        {
            visible = value;
        }

        public function getVisibleState():Boolean
        {
            return visible;
        }

        public function setLocation(location:Point):void
        {
            point = location;
        }

        public function getLocation():Point
        {
            return point;
        }

        public function move(dx:Number, dy:Number):void
        {
            point.offset(dx, dy);
        }
    }
}

Класс BlitLayerCanvas представляет собой bitmapData , к которому вы можете copyPixels () отдельные битовые карты, но они не отображаются на экране, потому что они не добавляются в список отображения. Надеемся, что просмотр этого класса поможет вам скопировать объекты на холст, который существует в памяти, но не отображается. (Совет: если вы знаете, что не собираетесь добавлять его в список отображения, вам на самом деле не нужно использовать контейнерный класс Bitmap .)

package com.lunchmeat317.blitter
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    /**
     * ...
     * @author lunchmeat317
     */
    public final class BlitLayerCanvas extends BLOB
    {
        public var bloblist:Vector.<BLOB>;

        public function BlitLayerCanvas(width:uint, height:uint, x_pos:int, y_pos:int, x_rectpos:uint, y_rectpos:uint)
        {
            super(width, height, x_pos, y_pos, x_rectpos, y_rectpos, new BitmapData(width, height, true, 0x0));

            bloblist = new Vector.<BLOB>();
        }

        public function addObject(obj:BLOB):void
        {
            bloblist.push(obj);
            trace("BLOB added to bloblist");
        }

        public function update():void
        {
            for each (var x:BLOB in bloblist)
            {
                data.copyPixels(x.data, x.rect, x.point, null, null, true);
            }
        }

        public function flush():void
        {
            data.fillRect(data.rect, 0x0);
        }
    }
}

Есть еще два класса, но они в значительной степени похожи друг на друга - один класс для слоев без холста (в основном, вектор BLOB) и последний класс, который обновляет экран. Они работают одинаково.

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

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...