软硬度:为什么TileList的图像消失的阻力? [英] Flex: Why are TileList images disappearing on drag?

查看:153
本文介绍了软硬度:为什么TileList的图像消失的阻力?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Flex航空(桌面)的应用程序加载从本地文件系统映像到一个TileList。然后,用户将能够拖动(复制)这些图像在这个清单上的另一控制

我终于拿到了图像显示正确(和滚动TileList的后不消失),但他们似乎从TileList中消失在拖动操作的开始。

我来自一个.NET的背景和我刚学AS3 / Flex的,所以如果你使用任何反模式在这里看到我,请随时提出来!

样品code如下(我试图使这一尽可能小)。


Test.mxml:

 < XML版本=1.0编码=UTF-8&GT?;
< S:的WindowedApplication的xmlns:FX =htt​​p://ns.adobe.com/mxml/2009
                       XMLNS:S =库://ns.adobe.com/flex/spark
                       的xmlns:MX =库://ns.adobe.com/flex/mx>
    < FX:脚本>
        <![CDATA [

            进口mx.collections.ArrayCollection;
            进口mx.events.FlexEvent;

            [可绑定]
            保护VAR _pics:ArrayCollection的=新ArrayCollection的();

            保护功能picsList_creationCompleteHandler(事件:FlexEvent):无效
            {
                常量imageFolderPath:字符串=C:\\用户\\ bbrooks \\图片;

                VAR IMAGEDIR:文件=新的文件(imageFolderPath);
                VAR的图像文件:阵列= imageDir.getDirectoryListing();
                每个(VAR镜像文件:文件中的图像文件)
                {
                    _pics.addItem(新PictureObject(imageFile.nativePath));
                }

                //给图像一个机会来加载
                VAR定时器:定时器=新的定时器(1000);
                timer.addEventListener(TimerEvent.TIMER,onTimerExpired);
                timer.start();
            }

            保护功能onTimerExpired(事件:TimerEvent):无效
            {
                picsList.dataProvider = _pics;
            }

        ]]≥
    < / FX:脚本>

    &所述;的mx:TileList中的id =picsList×=0Y =0的宽度=100%高度=100%dragEnabled =真dragMoveEnabled =假
                 的creationComplete =picsList_creationCompleteHandler(事件)>
        < MX:itemRenderer的>
            < FX:成分>
                < MX:图像宽度=75高度=75来源={data.image}/>
            < / FX:成分>
        < / MX:itemRenderer的>
    < / MX:TileList的>

&所述; /秒:的WindowedApplication>
 


PictureObject.as:

 包
{
    进口flash.display.Loader;
    进口flash.display.LoaderInfo;
    进口对象类型:flash.events.Event;
    进口flash.net.URLRequest;

    进口mx.controls.Image;

    [可绑定]
    [为RemoteClass]
    公共类PictureObject扩展对象
    {
        保护VAR _image:图片= NULL;
        公共函数来获取图像():图像{返回_image; }
        公共功能集图像(为newValue:图片):无效{_image =为newValue; }

        公共职能PictureObject(路径:字符串)
        {
            VAR ImageLoader的:装载机=新的Loader();
            imageLoader.contentLoaderInfo.addEventListener(引发Event.COMPLETE,onImageLoaded);
            imageLoader.load(新的URLRequest(路径));
        }

        保护功能onImageLoaded(五:事件):无效
        {
            VAR ImageLoader的:装载机=的LoaderInfo(e.target).loader;
            VAR BMP:位图=位图(imageLoader.content);

            _image =新的图像();
            _image.smoothBitmapContent = TRUE;
            _image.source =新位图(bmp.bitmapData);
            _image.width = imageLoader.width;
            _image.height = imageLoader.height;
        }
    }
}
 

解决方案

我将主要回答您的第二个问题(猜测这将解决一举初级):作为反模式走,这不是一个坏榜样;)

  1. 您是手动加载图像,而图片类有内置的负荷;只要给一个网址到它的属性,它会自动加载它。
  2. 您要设置一个图片实例作为另一个图片实例源;在属性需要网址或ByteArray对象;我很惊讶它不会引发错误; Image类可能是足够聪明的提取其它图像的实例。
  3. 定时器是多余的。至于说,一个图片会自动加载其内容的照顾。
  4. S:图片标记不包括在的ItemRenderer ,因此应该有一个没有访问数据属性:此code甚至不应该编译
  5. 有一个在具有可绑定属性没有意义 _pics ,如果你不打算约束它。
  6. 您使用MX的TileList。为什么不使用更现代星火版本? (这并不意味着对MX类将不会在Spark应用程序的工作,虽然)。

所以,你有很多删去做。您可以完全报废PictureObject类;删除计时器code;和公正的URL字符串添加到 _pics 集合。作为一个加号,你也可以更换MX的TileList与星火列表TileLayout;是这样的:

 < S:列表ID =picsList>
    < S:布局>
        &所述氏:TileLayout />
    < / S:布局>
    < S:itemRenderer的>
        < FX:成分>
            < S:ItemRenderer的>
                < S:图片来源={}数据/>
            < / S:ItemRenderer的>
        < / FX:成分>
    < / S:itemRenderer的>
< / S:列表>
 

ActionScript的部分可以减少到这一点:

 常量imageFolderPath:字符串=C:\\用户\\ bbrooks \\图片;

VAR IMAGEDIR:文件=新的文件(imageFolderPath);
VAR的图像文件:阵列= imageDir.getDirectoryListing();
picsList.dataProvider =新ArrayCollection的(图像文件中);
 

I'm developing a Flex Air (desktop) application that loads images from the local filesystem into a TileList. The user will then be able to drag (copy) these images out of the list onto another control.

I've finally got the images showing up correctly (and not disappearing after scrolling the TileList) but they seem to disappear from the TileList at the start of a drag operation.

I come from a .NET background and am just learning AS3/Flex, so if you see me using any anti-patterns here, feel free to point them out!

Sample code follows (I've tried to make this as minimal as possible).


Test.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Script>
        <![CDATA[

            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;

            [Bindable]
            protected var _pics:ArrayCollection = new ArrayCollection();

            protected function picsList_creationCompleteHandler(event:FlexEvent):void
            {
                const imageFolderPath:String = "c:\\users\\bbrooks\\Pictures";

                var imageDir:File = new File(imageFolderPath);
                var imageFiles:Array = imageDir.getDirectoryListing();
                for each(var imageFile:File in imageFiles)
                {
                    _pics.addItem(new PictureObject(imageFile.nativePath));
                }

                // give images a chance to load
                var timer:Timer = new Timer(1000);
                timer.addEventListener(TimerEvent.TIMER, onTimerExpired);
                timer.start();
            }

            protected function onTimerExpired(event:TimerEvent):void
            {
                picsList.dataProvider = _pics;
            }

        ]]>
    </fx:Script>

    <mx:TileList id="picsList" x="0" y="0" width="100%" height="100%" dragEnabled="true" dragMoveEnabled="false"
                 creationComplete="picsList_creationCompleteHandler(event)" >
        <mx:itemRenderer>
            <fx:Component>
                <mx:Image width="75" height="75" source="{data.image}" />
            </fx:Component>
        </mx:itemRenderer>
    </mx:TileList>

</s:WindowedApplication>


PictureObject.as:

package
{
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.events.Event;
    import flash.net.URLRequest;

    import mx.controls.Image;

    [Bindable]
    [RemoteClass]
    public class PictureObject extends Object
    {
        protected var _image:Image = null;
        public function get image():Image { return _image; }
        public function set image(newValue:Image):void { _image = newValue; }

        public function PictureObject(path:String)
        {
            var imageLoader:Loader = new Loader();
            imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
            imageLoader.load(new URLRequest(path));
        }

        protected function onImageLoaded(e:Event):void
        {
            var imageLoader:Loader = LoaderInfo(e.target).loader;
            var bmp:Bitmap = Bitmap(imageLoader.content);

            _image = new Image();           
            _image.smoothBitmapContent = true;
            _image.source = new Bitmap(bmp.bitmapData);
            _image.width = imageLoader.width;
            _image.height = imageLoader.height;
        }
    }
}

解决方案

I will mostly reply to your secondary question (guessing it will resolve the primary in one fell swoop): as anti-patterns go, this is not a bad example ;)

  1. You are manually loading the images while the Image class has the loading built-in; just give a URL to its source property and it will automatically load it.
  2. You are setting an Image instance as the source of another Image instance; the source property expects URLs or ByteArrays; I'm surprised it doesn't throw an error; the Image class is probably smart enough to extract the source of the other Image instance.
  3. The Timer is redundant. As said, an Image automatically takes care of loading its content.
  4. The s:Image tag isn't wrapped in an ItemRenderer and hence should have no access to a data property: this code shouldn't even compile.
  5. There's no point in having a Bindable property _pics if you don't plan on binding it.
  6. You use the mx TileList. Why not use the more "modern" Spark version? (This doesn't mean the mx class won't work in a Spark application though).

So you have a lot of deleting to do. You can scrap the PictureObject class altogether; remove the Timer code; and just add the URL Strings to the _pics collection. As a plus you could also replace the mx TileList with a Spark List with TileLayout; something like this:

<s:List id="picsList">
    <s:layout>
        <s:TileLayout />
    </s:layout>
    <s:itemRenderer>
        <fx:Component>
            <s:ItemRenderer>
                <s:Image source="{data}" />
            </s:ItemRenderer>
        </fx:Component>
    </s:itemRenderer>
</s:List>

The ActionScript part could be reduced to this:

const imageFolderPath:String = "c:\\users\\bbrooks\\Pictures";

var imageDir:File = new File(imageFolderPath);
var imageFiles:Array = imageDir.getDirectoryListing();
picsList.dataProvider = new ArrayCollection(imageFiles);

这篇关于软硬度:为什么TileList的图像消失的阻力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆