使用 ItemAppearing 事件在 ListView 中向下滚动会跳过 Xamarin.Forms 中的记录

Scrolldown in ListView using ItemAppearing event skips records in Xamarin.Forms

我在 Xamarin 页面中有 ListView。我使用 ItemAppearing 事件向下滚动。 ListViewCell 高度很大,所以第一个屏幕覆盖第二个视单元的 80%。

为向下滚动加载更多数据的步骤:

  1. 最初当页面加载时,它调用 API 并获得 10 条记录 雇主结果列表。这将被添加到 ListView 中使用 数据绑定。
  2. 正在举办 ItemAppearing 活动。这个事件有一个条件。 当最后一个单元格开始出现时,它将调用 API 并再次追加 10 记录在 ViewModel 的 List 对象中。
  3. 所以,这样它会调用 API 并且每次追加 10 条记录 最后一个单元格开始出现。

现在点在每次加载时,它会跳过最后一条记录并显示下 10 条记录的第一条记录。但是,如果用户快速向下滚动,有时它会跳过 2-3 条记录。

即如果我第一次有 10 条记录。现在我在第 9 条记录上,我正在向下滚动到 10。第 10 条记录开始出现并且 API 呼叫触发。此调用完成后,屏幕将在屏幕顶部显示第 11 条记录。这里,第 10 条记录被跳过。这样用户将看到第 11 条记录而不是第 10 条记录。此处用户需要再次向上滚动才能看到第 10 条记录。

有时,如果用户快速向下滚动,它会跳过 2-3 条记录。

有人可以给我建议吗?

代码

XAML

<ListView Grid.Row="0" x:Name="EmployerResultsListView"
          ItemsSource="{Binding EmployerResults}"
          HasUnevenRows = "true"
          SeparatorVisibility="None"
          IsPullToRefreshEnabled="true"
          RefreshCommand="{Binding RefreshCommand}"
          IsRefreshing="{Binding IsRefreshing, Mode=OneWay}"
          ItemAppearing="Handle_ItemAppearing"
          ItemTapped="OnEmployerResultsListViewItemTapped">
    <ListView.ItemTemplate>
        <DataTemplate>
            <local:EmployerResultViewCell />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

XAML.CS

private void Handle_ItemAppearing(object sender, ItemVisibilityEventArgs e)
{
    var itemTypeObject = e.Item as EmployerProfile;
    if (_viewModel.EmployerResults.Last() == itemTypeObject && _viewModel.EmployerResults.Count() != 1)
    {
        if (_viewModel.LoadMoreCommand.CanExecute(null))
        {
            _viewModel.LoadMoreCommand.Execute(null);
        }
    }
}

视图模型

public EmployerResultsViewModel()
{
    LoadMoreCommand = new RelayCommand(LoadMoreEmployerResult, () => !IsBusy);
    EmployerResults = new ObservableRangeCollection<EmployerProfile>();
}
public ObservableRangeCollection<EmployerProfile> EmployerResults { get; set; }

private async void LoadMoreEmployerResult()
{
    IsBusy = true;
    EmployerResults.AddRange((await _employerApiClient.GetMoreData(pagenumber)));
    IsBusy = false;
}

据我了解,您正在尝试进行延迟加载。

-首先,您应该像这样设置回收策略:CachingStrategy="RecycleElement" 如果您想要此处描述的可接受的性能 https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/performance,然后重新测试 ItemAppearing 事件的行为。

-那么,使用或分析满足您需求的现有组件可能是个好主意。例如:http://15mgm15.ghost.io/2017/11/28/implement-an-infinite-scrolling-listview-with-xamarin-forms/

我所做的是在 LoadMoreEmployerResult 的末尾添加额外的空白单元格,并要求在其上显示更多内容。在加载更多时,我删除了那个空白单元格。这是我认为可以解决我的问题的唯一方法。

private async void LoadMoreEmployerResult()
{
    IsBusy = true;
    if(EmployerResults.Last().Name == "")
        EmployerResults.RemoveAt(EmployerResults.Count - 1);
    List<EmployerProfile> currentPageList= await _employerApiClient.GetMoreData(pagenumber);
    if(currentPageList.Count > 0)
    {
        EmployerResults.AddRange(currentPageList);
        EmployerResults.Add(new EmployerProfile());
    }

    IsBusy = false;
}