【问题标题】:Xamarin listview with images don't scroll smoothly带有图像的 Xamarin 列表视图滚动不顺畅
【发布时间】:2019-03-20 03:42:16
【问题描述】:

我正在开发一个博客应用程序,我在每个项目列表中放置了一张卡片。在这些卡片中,有标签和图像。问题是当 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) 在列表视图的每个单元格中显示数据

<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的代码/xaml吗?
  • @Nick 你能在看到我的代码后提出建议吗?
  • 我将首先简化您的DataTemplate 并从中删除尽可能多的额外视图。似乎有很多额外的StackLayouts 可能会被您已经拥有的Grid 所取代。另外,如果您可以不设置 HasUnevenRows="True" 单独在您的列表视图上可能会加快速度,然后我会从那里去查看您的 ff:CachedImage 问题。

标签: android xamarin xamarin.forms xamarin.android


【解决方案1】:

首先,确保您的缓存策略是 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();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    相关资源
    最近更新 更多