我正在开发一个博客应用程序,我在每个项目列表中都放了一张卡片。在这些卡中,有标签和图像。问题是当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中的Recycle元素。
然后,为防止图像出现在错误的单元格中,请扩展自定义视单元格,并更改图像的来源。你可以查看official documentation。
看一个例子:
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();
}
}