我正在开发一个博客应用程序,其中我在每个项目列表中放置了一张卡。在这些卡中,有标签和图像。问题是当ListView加载时,它不会与图像顺利滚动,而我的图像来自URI。我还使用了最新的ffimageloading插件,但问题仍然相同。甚至还有其他问题,此插件没有缓存正确的图像。
我已经在互联网上搜索了很多东西,它开始觉得Xamarin对此没有任何解决方案。最后一个希望只是这个问题。
我的XAML页
<ContentPage.BindingContext>
<local1:HomeViewModel/>
</ContentPage.BindingContext>
<ListView x:Name="listView" SelectedItem="{Binding SelcetedItem,Mode=TwoWay}" SeparatorVisibility="None"
RowHeight="150"
ItemsSource="{Binding Items}" CachingStrategy="RecycleElement" HasUnevenRows="True" >
<ListView.Behaviors>
<extended:InfiniteScrollBehavior IsLoadingMore="{Binding IsBusy}" />
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<local:CardViewTemplate />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Footer>
<Grid Padding="6" IsVisible="{Binding IsBusy}">
<Grid.Triggers>
<Trigger TargetType="Grid" Property="IsVisible" Value="False">
<Setter Property="HeightRequest" Value="0" />
</Trigger>
</Grid.Triggers>
<Label Text="Loading..." TextColor="DeepPink" FontSize="20" FontAttributes="Bold" VerticalOptions="Center" HorizontalOptions="Center" />
</Grid>
</ListView.Footer>
BindingContext HomeviewModel.cs
public HomeViewModel()
{
Items = new InfiniteScrollCollection<HomeDto>
{
OnLoadMore = async () =>
{
IsBusy = true;
// load the next page
var page = Items.Count / PageSize;
var items = await _dataService.GetItemsAsync(page, PageSize);
IsBusy = false;
// return the items that need to be added
return items;
},
OnCanLoadMore = () =>
{
return Items.Count < Convert.ToInt32(_dataService.CardDataCollection.Count);
}
};
DownloadDataAsync();
}
数据来自这里
private void GenerateCardModel()
{
CardDataCollection = HomeServiceHelper.AllArticles();
foreach(var item in CardDataCollection)
{
item.ImageUrl = "http://192.168.31.204:8080/" + item.ImageUrl;
}
}
public async Task<List<HomeDto>> GetItemsAsync(int pageIndex, int pageSize)
{
await Task.Delay(2000);
return CardDataCollection.Skip(pageIndex * pageSize).Take(pageSize).ToList();
}
最后,我的帧(cardViewTemplate.xAML)在ListView的每个单元格中显示数据
<Frame IsClippedToBounds="True"
HasShadow="True"
BackgroundColor="White" CornerRadius="5" Margin="10" >
<StackLayout Orientation="Horizontal">
<Grid VerticalOptions="CenterAndExpand" Padding="0" HorizontalOptions="FillAndExpand" BackgroundColor="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Row="0" Grid.Column="0">
<Label FontAttributes="None" HorizontalTextAlignment="Start" VerticalTextAlignment="Start" FontSize="18"
FontFamily="Arial" Text="{Binding ArticleHeading, Mode = TwoWay}" LineBreakMode="TailTruncation" TextColor="#212121"
MaxLines="3">
</Label>
</StackLayout>
<StackLayout Grid.Row="0" Grid.Column="1" BackgroundColor="Yellow" WidthRequest="70" HorizontalOptions="EndAndExpand"
VerticalOptions="FillAndExpand">
<ff:CachedImage Source="{Binding ImageUrl}" HorizontalOptions="FillAndExpand" CacheType="Memory">
</ff:CachedImage>
</StackLayout>
<StackLayout Grid.Row="1" Grid.Column="0" Orientation="Horizontal">
<Label FontAttributes="None" HorizontalTextAlignment="Start" VerticalTextAlignment="Center"
FontSize="14" Text="{Binding Admin , Mode = TwoWay}" TextColor="#212121" >
</Label>
<Label FontAttributes="None" HorizontalTextAlignment="Start" VerticalTextAlignment="Center"
FontSize="14" Text="{Binding LastModifiedOn , Mode = TwoWay, StringFormat='{0:d}'}" TextColor="Gray" >
</Label>
</StackLayout>
</Grid>
</StackLayout>
</Frame>
首先,确保您的缓存策略是ListView中的回收元素。
然后,为了防止在错误的单元格中出现图像,请扩展自定义视图并更改图像源。您可以检查官方文档。
请参阅一个示例:
public class MyCustomCell : ViewCell
{
readonly CachedImage cachedImage = null;
public MyCustomCell()
{
cachedImage = new CachedImage();
View = cachedImage;
}
protected override void OnBindingContextChanged()
{
// you can also put cachedImage.Source = null; here to prevent showing old images occasionally
cachedImage.Source = null;
//Cast the respective model.
var item = BindingContext as Item;
if (item == null)
{
return;
}
cachedImage.Source = item.ImageUrl;
base.OnBindingContextChanged();
}
}