无限滚动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
是一个字符串。
我应该以这种方式创建映像,还是有更好的方法来优化我的代码?
我也有类似的问题。我已经通过实现自己的下载图像队列解决了它。一次只需下载一张图像,因此您只有一个线程。
您可能认为图像下载速度会变慢,但事实并非如此。同时下载所有 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>