无限滚动WP8长名单选择器与图像

本文关键字:选择器 图像 名单 滚动 WP8 无限 | 更新日期: 2023-09-27 18:34:22

我有一个 LongListSelector,我用它来显示一堆图像,就像缩略图一样。在滚动(无限滚动场景(的某个时间点,图像正在下载并且应用程序变慢(即在 LongListSelector 上滚动变得很慢(后,图像显示后应用程序再次恢复活力。

我正在使用如下所示的 xaml:

<Image Stretch="UniformToFill" 
      Margin="-3,0,0,0" 
      Source="{Binding video_thumbnail}" 
      Opacity="1" 
      Height="200" Width="480" />

video_thumbnail是一个字符串。

我应该以这种方式创建映像,还是有更好的方法来优化我的代码?

无限滚动WP8长名单选择器与图像

我也有类似的问题。我已经通过实现自己的下载图像队列解决了它。一次只需下载一张图像,因此您只有一个线程。

您可能认为图像下载速度会变慢,但事实并非如此。同时下载所有 5 张图像时,逐个下载 5 张图像所需的时间相同。我在自己的应用程序中对其进行了测试。

这是我的例子。首先,我创建了一个类来存储有关视频的基本信息:缩略图的 url 和缩略图本身作为 ImageSource ,因此您可以轻松地将其绑定到 XAML 中Image属性Source

public class VideoItem
{
    public string Url { get; private set; }
    public ImageSource Thumbnail { get; set; }
    public VideoItem(string url)
    {
        this.Url = url;
    }
}

下一个类将所有视频存储在一个可观察列表中,因此您可以在绑定中使用它。该列表将随着缩略图的逐个下载而增长。

public class VideoLibrary
{
    private WebClient thumbnailDownloader = new WebClient();
    private Queue<VideoItem> downloadQueue = new Queue<VideoItem>();
    private bool isBusy = false;
    public ObservableCollection<VideoItem> Videos = new ObservableCollection<VideoItem>();
    public VideoLibrary()
    {
        thumbnailDownloader.OpenReadCompleted += OnThumbnailDownloaded;
    }
    // It will not start downloading process but only add a new video item (without thumbnail) to download queue.
    public void Download(string url)
    {
        downloadQueue.Enqueue(new VideoItem(url)); // Just add to queue.
        CheckQueue();
    }
    // Check whether there are new thumbnails to download. If so, start downloading just one.
    private void CheckQueue()
    {
        if (isBusy) // Stop! Downloading in progress...
            return;
        if (downloadQueue.Count > 0)
        {
            isBusy = true;
            VideoItem item = downloadQueue.Peek();
            thumbnailDownloader.OpenReadAsync(new Uri(item.Url));
        }
    }
    // One thumbnail has been downloaded. We can add it to the list of videos and check the queue again.
    private void OnThumbnailDownloaded(object sender, OpenReadCompletedEventArgs e)
    {
        isBusy = false;
        if (e.Cancelled)
        {
            CheckQueue(); // Just try again.
        }
        else if (e.Error != null)
        {
            downloadQueue.Dequeue(); // Skip this video (thumbnail), check the next one.
            CheckQueue();
        }
        else if (downloadQueue.Count > 0)
        {
            VideoItem item = downloadQueue.Dequeue(); // Remove the video from queue.
            WriteableBitmap bitmap = new WriteableBitmap(null); 
            bitmap.SetSource(e.Result);
            item.Thumbnail = bitmap; // Thumbnail is ready to use.
            Videos.Add(item); // Add to list.
            CheckQueue();
        }
    }
}

根据这篇文章:

  • 切勿将服务器承载的图像直接绑定到控件,因为 Silverlight 运行时将使用 UI 线程(使用 WebClient(从服务器提取该图像,这可能会使 UI 在一段时间内无响应。

  • 使用后台线程和基于HttpWebRequest类的实现以有效的方式下载图像数据,最终创建BitmapImage并将其设置为源。围绕这一点的干净 MVVM 包装器将使您的整个映像管理变得非常容易。

另外,请浏览Windows Phone开发的最佳实践

  • 将 BitMapCredtiOptions 值设置为 BackGroundCreation。这将允许它使用缓存的图像(如果 UriSource 已存在缓存的图像(。

  • 如果图像尺寸较大,例如许多手机摄像头捕获的高分辨率图像,则在解码图像的所有像素时可能会消耗相当多的CPU处理。如果您知道要渲染的图像帧的大小,则可以使用该信息来设置要解码的像素大小。

  <Image ..>
    <Image.Source> 
         <BitmapImage
             UriSource="{Binding video_thumbnail}"
             CreateOptions="BackgroundCreation"/> 
   </Image.Source> 
 </Image>