开发者

Spark images in spark list with TileLayout disappear on scroll and drag in Flex app

开发者 https://www.devze.com 2023-03-17 03:59 出处:网络
I have a renderer that looks like this: <s:ItemRenderer xmlns:fx=\"http://ns.adobe.com/mxml/2009\"

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+"Unknow开发者_开发技巧n.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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号