Flex:为什么 TileList 图像在拖动时消失? [英] Flex: Why are TileList images disappearing on drag?

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

问题描述

我正在开发一个 Flex Air(桌面)应用程序,它将图像从本地文件系统加载到 TileList.然后,用户将能够将这些图像从列表中拖出(复制)到另一个控件上.

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.

我终于让图像正确显示(并且在滚动 TileList 后没有消失),但它们似乎在拖动操作开始时从 TileList 中消失.

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.

我来自 .NET 背景并且刚刚学习 AS3/Flex,所以如果您看到我在这里使用任何反模式,请随时指出它们!

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. 您正在手动加载图像,而 Image 类具有内置的加载功能;只需为其 source 属性提供一个 URL,它就会自动加载它.
  2. 您正在将一个 Image 实例设置为另一个 Image 实例的源;source 属性需要 URL 或 ByteArray;我很惊讶它没有抛出错误;Image 类可能足够聪明,可以提取另一个 Image 实例的source.
  3. Timer 是多余的.如前所述,Image 会自动负责加载其内容.
  4. s:Image 标记未包含在 ItemRenderer 中,因此不应访问 data 属性:此代码应该甚至无法编译.
  5. 如果您不打算绑定它,那么拥有 Bindable 属性 _pics 是没有意义的.
  6. 您使用 mx TileList.为什么不使用更现代"的 Spark 版本?(但这并不意味着 mx 类在 Spark 应用程序中不起作用).
  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).

所以你有很多删除工作要做.您可以完全废弃 PictureObject 类;删除定时器代码;并将 URL 字符串添加到 _pics 集合中.作为一个加号,您还可以将 mx TileList 替换为带有 TileLayout 的 Spark 列表;像这样:

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>

ActionScript 部分可以简化为:

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);

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

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