带有图像的 Xamarin 列表视图无法流畅滚动



我正在开发一个博客应用程序,其中我在每个项目列表中放置了一张卡。在这些卡中,有标签和图像。问题是当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();
    }
}

最新更新