使用 TileLayout 的 Spark 列表中的 Spark 图像在 Flex 应用程序中滚动和拖动时消失
我有一个如下所示的渲染器:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:Group width="160" toolTip="{data.toolTip}" doubleClickEnabled="true">
<s:layout>
<s:VerticalLayout gap="5" horizontalAlign="center"
paddingBottom="2" paddingLeft="2" paddingRight="2" paddingTop="2"/>
</s:layout>
<mx:Canvas width="156" height="156" borderStyle="solid" borderColor="#AAAAAA"
verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:Image id="image" source="{data.thumbnail}" width="{data.thumbwidth}" height="{data.thumbheight}"
horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
<s:Label text="{data.data.name}" maxDisplayedLines="2" textAlign="center"
width="100%"/>
</s:Group>
</s:ItemRenderer>
在一个如下所示的列表中
<s:List id="fileIconView"
dataProvider="{files}"
width="100%" height="100%"
borderVisible="false"
dragEnabled="true"
allowMultipleSelection="true"
doubleClickEnabled="true"
mouseDown="fileIconViewMouseDown(event)"
mouseMove="fileIconViewMouseMove(event)"
mouseUp="clearSelectionRectangle()"
change="fileSelectionChanged()"
itemRenderer="view.ThumbnailRenderer">
<s:layout>
<s:TileLayout clipAndEnableScrolling="true" />
</s:layout>
</s:List>
当我滚动列表中的图像时消失。我该如何解决这个问题?
当我拖动其中一个时,也会发生同样的情况,但我通过在拖动完成或取消时重新生成列表来修复该问题(部分)。
更新时间:美国东部时间 2011 年 7 月 11 日下午 2:02 发送到渲染器的数据对象如下所示
[Bindable]
public class FileWrapper
{
/** file that wrapper holds, File, OnlineDocument and SymbolicLinks */
public var data:*;
/** file size */
public var size:String;
/** file's author */
public var author:String;
/** file's created date */
public var date:String;
/** tooltip for the file */
public var toolTip:String;
/** image */
public var img:String;
/** thumbnail source */
public var thumbnail:Object;
/** width of thumbnail image */
public var thumbwidth:int;
/** height of thumbnail image */
public var thumbheight:int;
/** folder with mime type icons */
public const MIME_ICONS_FOLDER:String = "fileexplorer/mimeTypeIcons/";
public function FileWrapper(file:*, controller:FileExplorerController)
{
this.data = file;
if (file is File) {
var f:File = file as File;
this.size = NumberUtils.humanReadableBytes(f.latestRevision.sizeOnDisk);
this.author = f.latestRevision.author.displayName;
this.date = NumberUtils.formatDate(f.latestRevision.timeUploaded);
this.toolTip = f.name + "\n" +"Size: " + this.size
+ "\n" + "Type: " + f.latestRevision.mimeType;
this.img = MIME_ICONS_FOLDER+getMimeTypeIcon(f.latestRevision.mimeType);
var self:FileWrapper = this;
controller.getThumbnail(f.latestRevision,
function (tumbnailBitmap:Object):void
{
self.thumbnail = tumbnailBitmap;
self.thumbwidth = tumbnailBitmap.width;
self.thumbheight = tumbnailBitmap.height;
});
}
else if(file is OnlineDocument) {
this.toolTip = file.name + "\nOnline Document";
this.img = MIME_ICONS_FOLDER+"OnlineDocument.png";
}
else if(file is SymbolicFileLink) {
this.toolTip = file.name + "\nShortcut";
this.img = MIME_ICONS_FOLDER+"System-Shortcut-icon.png";
}
else {
this.size = "";
this.author = "";
this.date = "";
this.toolTip = "Unknown File Type";
this.img = MIME_ICONS_FOLDER+"Unknown.png";
}
this.thumbnail = this.img;
this.thumbwidth = 32;
this.thumbheight = 32;
}
/**
* Gets the icon image for the given mime type
*
* @param mime type string
* @return image name string
*/
protected static function getMimeTypeIcon(mimeType:String):String
{
switch (mimeType) {
case "application/msword":
return "File-doc.png";
case "application/octet-stream":
return "System-binary.png";
case "application/ogg":
return "Audio-ogg.png";
case "application/pdf":
return "File-pdf.png";
case "application/vnd.ms-excel":
return "File-xls.png";
case "application/vnd.ms-powerpoint":
return "File-ppt.png";
case "application/x-bzip2":
return "Archive-zip.png";
case "application/x-gtar":
return "Archive-tar.png";
case "application/x-gzip":
return "Archive-gzip.png";
case "application/x-tar":
return "Archive-tar.png";
case "application/xhtml+xml":
return "File-html.png";
case "application/zip":
return "Archive-zip.png";
case "audio/x-mpegurl":
return "Audio-mp3.png";
case "audio/mpeg":
return "Audio-mp3.png";
case "audio/x-aiff":
return "Audio-aiff.png";
case "audio/x-wav":
return "Audio-wav.png";
case "image/bmp":
return "Image-bmp.png";
case "image/gif":
return "Image-gif.png";
case "image/jpeg":
return "Image-jpg.png";
case "image/png":
return "Image-png.png";
case "image/tiff":
return "Image-bmp.png";
case "text/html":
return "File-html.png";
case "text/plain":
return "File-txt.png";
case "application/vnd.oasis.opendocument.presentation":
return "Presentation.png";
case "application/vnd.oasis.opendocument.spreadsheet":
return "Spreadsheet.png";
case "application/vnd.oasis.opendocument.text":
case "text/richtext":
return "Text.png";
case "text/xml":
return "Text.png";
case "video/mpeg":
return "Video-mpeg.png";
case "video/quicktime":
return "Video-movie.png";
case "video/vnd.mpegurl":
return "Video-mpeg.png";
case "video/x-msvideo":
return "Video-avi.png";
case "video/x-sgi-movie":
return "Video-movie.png";
default:
return "System-default.png";
}
}
}
。controller.getThumbnail 方法只需调用此模型方法,
public function getThumbnail(revision:Revision, callBack:Function):void
{
// only for image revisions
if (revision.mimeType.indexOf("image") > -1) {
var loader:Loader = new Loader();
// create request
var urlVars:URLVariables = new URLVariables();
urlVars.authToken = userAccountModel.token;
urlVars.id = revision.id;
var req:URLRequest = new URLRequest(THUMBNAIL_URL);
req.data = urlVars;
var context:LoaderContext = new LoaderContext(true);
loader.load(req, context);
// set load handler
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
function(event:Event):void
{
callBack(event.currentTarget.content);
});
}
}
使用此方法加载缩略图效果非常好。当您滚动列表时会出现此问题。
I have a renderer that looks like this:
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:Group width="160" toolTip="{data.toolTip}" doubleClickEnabled="true">
<s:layout>
<s:VerticalLayout gap="5" horizontalAlign="center"
paddingBottom="2" paddingLeft="2" paddingRight="2" paddingTop="2"/>
</s:layout>
<mx:Canvas width="156" height="156" borderStyle="solid" borderColor="#AAAAAA"
verticalScrollPolicy="off" horizontalScrollPolicy="off">
<mx:Image id="image" source="{data.thumbnail}" width="{data.thumbwidth}" height="{data.thumbheight}"
horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
<s:Label text="{data.data.name}" maxDisplayedLines="2" textAlign="center"
width="100%"/>
</s:Group>
</s:ItemRenderer>
In a list that looks like this
<s:List id="fileIconView"
dataProvider="{files}"
width="100%" height="100%"
borderVisible="false"
dragEnabled="true"
allowMultipleSelection="true"
doubleClickEnabled="true"
mouseDown="fileIconViewMouseDown(event)"
mouseMove="fileIconViewMouseMove(event)"
mouseUp="clearSelectionRectangle()"
change="fileSelectionChanged()"
itemRenderer="view.ThumbnailRenderer">
<s:layout>
<s:TileLayout clipAndEnableScrolling="true" />
</s:layout>
</s:List>
When I scroll the images in my list disappear. How do I fix this?
The same happens when I drag one of them but I fixed that (partially) by regenerating the list when the drag is completed or cancelled.
UPDATE July 11, 2011, 2:02PM EST
The data object being sent to the renderer looks like this
[Bindable]
public class FileWrapper
{
/** file that wrapper holds, File, OnlineDocument and SymbolicLinks */
public var data:*;
/** file size */
public var size:String;
/** file's author */
public var author:String;
/** file's created date */
public var date:String;
/** tooltip for the file */
public var toolTip:String;
/** image */
public var img:String;
/** thumbnail source */
public var thumbnail:Object;
/** width of thumbnail image */
public var thumbwidth:int;
/** height of thumbnail image */
public var thumbheight:int;
/** folder with mime type icons */
public const MIME_ICONS_FOLDER:String = "fileexplorer/mimeTypeIcons/";
public function FileWrapper(file:*, controller:FileExplorerController)
{
this.data = file;
if (file is File) {
var f:File = file as File;
this.size = NumberUtils.humanReadableBytes(f.latestRevision.sizeOnDisk);
this.author = f.latestRevision.author.displayName;
this.date = NumberUtils.formatDate(f.latestRevision.timeUploaded);
this.toolTip = f.name + "\n" +"Size: " + this.size
+ "\n" + "Type: " + f.latestRevision.mimeType;
this.img = MIME_ICONS_FOLDER+getMimeTypeIcon(f.latestRevision.mimeType);
var self:FileWrapper = this;
controller.getThumbnail(f.latestRevision,
function (tumbnailBitmap:Object):void
{
self.thumbnail = tumbnailBitmap;
self.thumbwidth = tumbnailBitmap.width;
self.thumbheight = tumbnailBitmap.height;
});
}
else if(file is OnlineDocument) {
this.toolTip = file.name + "\nOnline Document";
this.img = MIME_ICONS_FOLDER+"OnlineDocument.png";
}
else if(file is SymbolicFileLink) {
this.toolTip = file.name + "\nShortcut";
this.img = MIME_ICONS_FOLDER+"System-Shortcut-icon.png";
}
else {
this.size = "";
this.author = "";
this.date = "";
this.toolTip = "Unknown File Type";
this.img = MIME_ICONS_FOLDER+"Unknown.png";
}
this.thumbnail = this.img;
this.thumbwidth = 32;
this.thumbheight = 32;
}
/**
* Gets the icon image for the given mime type
*
* @param mime type string
* @return image name string
*/
protected static function getMimeTypeIcon(mimeType:String):String
{
switch (mimeType) {
case "application/msword":
return "File-doc.png";
case "application/octet-stream":
return "System-binary.png";
case "application/ogg":
return "Audio-ogg.png";
case "application/pdf":
return "File-pdf.png";
case "application/vnd.ms-excel":
return "File-xls.png";
case "application/vnd.ms-powerpoint":
return "File-ppt.png";
case "application/x-bzip2":
return "Archive-zip.png";
case "application/x-gtar":
return "Archive-tar.png";
case "application/x-gzip":
return "Archive-gzip.png";
case "application/x-tar":
return "Archive-tar.png";
case "application/xhtml+xml":
return "File-html.png";
case "application/zip":
return "Archive-zip.png";
case "audio/x-mpegurl":
return "Audio-mp3.png";
case "audio/mpeg":
return "Audio-mp3.png";
case "audio/x-aiff":
return "Audio-aiff.png";
case "audio/x-wav":
return "Audio-wav.png";
case "image/bmp":
return "Image-bmp.png";
case "image/gif":
return "Image-gif.png";
case "image/jpeg":
return "Image-jpg.png";
case "image/png":
return "Image-png.png";
case "image/tiff":
return "Image-bmp.png";
case "text/html":
return "File-html.png";
case "text/plain":
return "File-txt.png";
case "application/vnd.oasis.opendocument.presentation":
return "Presentation.png";
case "application/vnd.oasis.opendocument.spreadsheet":
return "Spreadsheet.png";
case "application/vnd.oasis.opendocument.text":
case "text/richtext":
return "Text.png";
case "text/xml":
return "Text.png";
case "video/mpeg":
return "Video-mpeg.png";
case "video/quicktime":
return "Video-movie.png";
case "video/vnd.mpegurl":
return "Video-mpeg.png";
case "video/x-msvideo":
return "Video-avi.png";
case "video/x-sgi-movie":
return "Video-movie.png";
default:
return "System-default.png";
}
}
}
The controller.getThumbnail method simply calls this model method
public function getThumbnail(revision:Revision, callBack:Function):void
{
// only for image revisions
if (revision.mimeType.indexOf("image") > -1) {
var loader:Loader = new Loader();
// create request
var urlVars:URLVariables = new URLVariables();
urlVars.authToken = userAccountModel.token;
urlVars.id = revision.id;
var req:URLRequest = new URLRequest(THUMBNAIL_URL);
req.data = urlVars;
var context:LoaderContext = new LoaderContext(true);
loader.load(req, context);
// set load handler
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
function(event:Event):void
{
callBack(event.currentTarget.content);
});
}
}
Loading thumbnails using this method works perfectly. The issue happens when you scroll the List.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当看到这样的东西时,我的第一个怀疑是“useVirtualLayout”问题。总而言之,当 useVirtualLayout 为 true(默认值)时,可以重新使用渲染器。当渲染器被重用时,它可能会认为数据实际上没有改变,并且会错误地渲染图像等内容。
我用来确保准确渲染的两种解决方案是:
首先,将 useVirtualLayout 设置为 false。这可以防止渲染器的重复使用。
其次,重写设置数据函数并创建您自己的私有变量来保存您正在显示的数据。这还将使您能够更轻松地调试数据设置,并确保每次使用/重新使用渲染器时都正确设置数据。
最后一点。这可能是完全不相关的,但我注意到在更新到 Flash Player 10.3 后这个特定问题出现的频率降低了。
My first suspicion when seeing something like this is a "useVirtualLayout" issue. To summarize, the renderer can be re-used when useVirtualLayout is true, the default. When a renderer gets reused it may decide that the data hasn't actually changed, and will incorrectly render things such as images.
The two solutions I have used to ensure accurate rendering are:
First, turn useVirtualLayout to false. This prevents the re-use of a renderer.
Second, override the set data function and create your own private variables to hold the data you are displaying. This will also allow you to more easily debug the setting of the data, and ensure the data is being set correctly every time the renderer is used/re-used.
One final note. It may be totally unrelated, but I noticed that this particular problem occurred less often after updating to Flash Player 10.3.