使用 ItemAppearing 事件在 ListView 中向下滚动会跳过 Xamarin.Forms 中的记录
Scrolldown in ListView using ItemAppearing event skips records in Xamarin.Forms
我在 Xamarin 页面中有 ListView
。我使用 ItemAppearing
事件向下滚动。 ListViewCell 高度很大,所以第一个屏幕覆盖第二个视单元的 80%。
为向下滚动加载更多数据的步骤:
- 最初当页面加载时,它调用 API 并获得 10 条记录
雇主结果列表。这将被添加到 ListView 中使用
数据绑定。
- 正在举办
ItemAppearing
活动。这个事件有一个条件。
当最后一个单元格开始出现时,它将调用 API 并再次追加 10
记录在 ViewModel 的 List 对象中。
- 所以,这样它会调用 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;
}
我在 Xamarin 页面中有 ListView
。我使用 ItemAppearing
事件向下滚动。 ListViewCell 高度很大,所以第一个屏幕覆盖第二个视单元的 80%。
为向下滚动加载更多数据的步骤:
- 最初当页面加载时,它调用 API 并获得 10 条记录 雇主结果列表。这将被添加到 ListView 中使用 数据绑定。
- 正在举办
ItemAppearing
活动。这个事件有一个条件。 当最后一个单元格开始出现时,它将调用 API 并再次追加 10 记录在 ViewModel 的 List 对象中。 - 所以,这样它会调用 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;
}