我正在使用Xamarin.Forms,使用MVVM。当我构建视图时,我使用嵌入在应用程序中的图像,使用 ImageSource.FromResource,一切都很好,我的所有图像都正确加载到视图中。当我将源更改为使用本地 Web 服务器中的 URI 时,视图上仅加载底部的 3 个图像。
我已经验证了服务器上是否存在所有图像,并且发送到图像源的 URI 是否正确。
我不确定为什么只加载了 3 张图像,其余的都是空白的。
这是我的代码:
视图模型:
private ObservableCollection<KnownBird> _knownBirds { get; set; }
public ObservableCollection<KnownBird> KnownBirds
{
get
{
return _knownBirds;
}
set
{
_knownBirds = value;
OnPropertyChanged("KnownBirds");
}
}
public KnownBirdsViewModel()
{
Title = "Known Birds";
KnownBirds = new ObservableCollection<KnownBird>();
LoadKnownBirdsCommand = new Command(async () => await ExecuteLoadBirdsCommand());
}
async Task ExecuteLoadBirdsCommand()
{
if (IsBusy)
return;
IsBusy = true;
try
{
KnownBirds.Clear();
var _birds = await BirdService.GetKnownBirdsAsync();
foreach (var tmpBird in _birds)
{
KnownBird tmpKB = new KnownBird();
tmpKB.BirdID = tmpBird.BirdID;
tmpKB.Name = tmpBird.Name;
tmpKB.examplePicture = tmpBird.examplePicture;
//Change this to URL when setting this from the REST API and not the local data.
//tmpKB.BirdImage = ImageSource.FromResource("BirdWatcherMobileApp.SampleData.images." + tmpBird.examplePicture);
tmpKB.BirdImage = ImageSource.FromUri(new Uri("http://" + Settings.ServerAddress + "/images/bird_examples/" + tmpBird.examplePicture));
KnownBirds.Add(tmpKB);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
视图:
<flv:FlowListView
FlowColumnCount="3"
HasUnevenRows="True"
FlowItemsSource="{Binding KnownBirds, Mode=OneWay}"
FlowItemTapped="FlowListView_FlowItemTapped"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
RefreshCommand="{Binding LoadKnownBirdsCommand}">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<StackLayout Orientation="Vertical" Margin="10" HeightRequest="125">
<Image Source="{Binding BirdImage, Mode=OneWay}" HeightRequest="100" />
<Label
Text="{Binding Name}"
FontSize="16"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Start"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
现在我认为从 Web 服务器加载图像需要时间,一旦图像加载到集合中,并且一旦发生绑定,ListView 永远不会更新绑定并且不会加载图像。
我读过,在使用 ObservableCollection 时,OnPropertyChanged 事件仅在从集合中添加或删除项时触发,而不是在更新项中的数据时触发。
我有一个 BindingList 集合将在更新列表中项内的数据时引发 OnPropertyChanged 事件。我试图用绑定列表替换 ObservableCollection,但随后注意到已加载到视图中。
我不确定如何从这里开始。我的怀疑正确吗?这里的任何帮助或信息将不胜感激!
我建议你使用FFImageLoad的CachedImage。
它是一个被社区广泛接受的库,非常适合缓存,并且还具有内存处理选项。
您可以查看他们的 Git wiki 以深入了解该库。
从Nuget下载它
在每个平台上呼叫CachedImageRenderer.Init()
。让我们把它放在我们的Android项目和iOSAppDelegate.cs
MainActivity.cs
上。
然后添加其命名空间并像这样使用它:
<ffimageloading:CachedImage
Source="{Binding BirdImage, Mode=OneWay}" HeightRequest="100" />
欲了解更多信息,你可以在这里查看我的博客
事实证明,这可能是由于 Xamarin 缓存了空图像。 我终于能够使用以下行显示所有这些:
tmpKB.BirdImage = new UriImageSource { CachingEnabled = false, Uri = new Uri("http://" + Settings.ServerAddress + "/images/bird_examples/" + tmpBird.examplePicture) };
并将"启用缓存"设置为 false。