我正在开发一个Flex Air(桌面)应用程序,它将来自本地文件系统的图像加载到TileList中。然后,用户可以将这些图像从列表中拖出(复制)到另一个控件上。
我终于正确显示了图像(并且在滚动TileList后没有消失)但是它们似乎在拖动操作开始时从TileList中消失。
我来自.NET背景,我只是在学习AS3 / Flex,所以如果你看到我在这里使用任何反模式,请随意指出它们!
示例代码如下(我试图尽量减少它)。
的 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;
}
}
}
答案 0 :(得分:1)
我将主要回复你的第二个问题(猜测它将一举解决主要问题):反模式去了,这不是一个坏的例子;)
Image
类内置加载时,您手动加载图像;只需为其source
属性提供一个URL,它就会自动加载它。Image
个实例作为另一个Image
实例的来源; source
属性需要URL或ByteArrays;我很惊讶它没有抛出错误; Image类可能足够智能,可以提取另一个Image实例的source
。Timer
是多余的。如上所述,Image
会自动负责加载其内容。s:Image
标记未包含在ItemRenderer
中,因此无法访问data
属性:此代码甚至不应编译。Bindable
属性_pics
是没有意义的。所以你有很多要删除的事情。你可以完全废弃PictureObject类;删除定时器代码;只需将URL字符串添加到_pics
集合中。作为一个加号你也可以用带有TileLayout的Spark List替换mx TileList;像这样的东西:
<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部分可以简化为:
const imageFolderPath:String = "c:\\users\\bbrooks\\Pictures";
var imageDir:File = new File(imageFolderPath);
var imageFiles:Array = imageDir.getDirectoryListing();
picsList.dataProvider = new ArrayCollection(imageFiles);
答案 1 :(得分:0)
感谢RIAstar。你的回答让我走上了解决问题的轨道。新的示例代码如下所示。
最初的问题似乎与mx:Image控件有关。不知道为什么,但使用s:图像控件似乎有效。
当然,只需将数据源设置为文件路径列表就可以在没有PictureObject类的情况下完成,但我稍后使用了图像数据,我希望通过提供图像数据来使其工作自定义渲染器动态。
<强> 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;
import spark.components.Image;
protected var _pics:ArrayCollection = new ArrayCollection();
protected function picsList_creationCompleteHandler(event:FlexEvent):void
{
const imageFolderPath:String = "c:\\users\\bbbrooks\\Pictures";
var imageDir:File = new File(imageFolderPath);
var imageFiles:Array = imageDir.getDirectoryListing();
for each(var imageFile:File in imageFiles)
{
if (imageFile.extension == "jpg")
{
_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>
<s:List id="picsList" x="0" y="0" width="100%" height="100%"
creationComplete="picsList_creationCompleteHandler(event)"
dragEnabled="true" dragMoveEnabled="false">
<s:layout>
<s:TileLayout />
</s:layout>
<s:itemRenderer>
<fx:Component>
<s:ItemRenderer>
<s:Image id="imageDisplay"
width="75" height="75" source="{data.bmp}" />
</s:ItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:List>
</s:WindowedApplication>
的 PictureObject.as 强>
package
{
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.net.URLRequest;
import mx.controls.Image;
[RemoteClass]
[Bindable]
public class PictureObject extends Object
{
protected var _bmp:Bitmap = null;
public function get bmp():Bitmap { return _bmp; }
public function set bmp(newValue:Bitmap):void { _bmp = 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;
// create our own copy of the bits in the Loader
var bmp:Bitmap = Bitmap(imageLoader.content);
_bmp = new Bitmap( Bitmap(imageLoader.content).bitmapData );
}
}
}