我已经创建了ListView,它有无限滚动和ObservableRangeCollection的帮助。它在Android上运行良好,但在iOS上它会在添加新项目时跳转。分页是通过行为来完成的。 ListView是一个FlowListView。 这是XAML:
...
FlowItemsSource="{Binding Profiles.Result}
...
<controls:FlowListView.Behaviors>
<behaviors:FlowListViewPaginating
Command="{Binding LoadMoreCommand}"
Converter="{StaticResource ItemVisibilityConverter}">
</behaviors:FlowListViewPaginating>
</controls:FlowListView.Behaviors>
...
行为:
public class FlowListViewPaginating : Behavior<FlowListView>
{
public FlowListView AssosiatedObject { get; private set; }
public static readonly BindableProperty CommandProperty =
BindableProperty.Create("Command", typeof(DelegateCommand<Profile>), typeof(FlowListViewPaginating), null);
public static readonly BindableProperty InputConverterProperty =
BindableProperty.Create("Converter", typeof(IValueConverter), typeof(FlowListViewPaginating), null);
public DelegateCommand<Profile> Command
{
get { return ( DelegateCommand<Profile> )GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public IValueConverter Converter
{
get { return ( IValueConverter )GetValue(InputConverterProperty); }
set { SetValue(InputConverterProperty, value); }
}
protected override void OnAttachedTo(FlowListView bindable)
{
base.OnAttachedTo(bindable);
AssosiatedObject = bindable;
bindable.BindingContextChanged += OnBindingContextChanged;
bindable.ItemAppearing += OnItemAppearing;
}
protected override void OnDetachingFrom(FlowListView bindable)
{
base.OnDetachingFrom(bindable);
bindable.BindingContextChanged -= OnBindingContextChanged;
bindable.ItemAppearing -= OnItemAppearing;
AssosiatedObject = null;
}
private void OnItemAppearing(object sender, ItemVisibilityEventArgs e)
{
var flowListView = ( FlowListView )sender;
if ( flowListView.IsRefreshing ) return;
if ( Command == null ) return;
var parameter = Converter.Convert(e, typeof(object), null, null) as Profile;
if ( Command.CanExecute(parameter) )
Command.Execute(parameter);
}
protected void OnBindingContextChanged(object sender, EventArgs e)
{
OnBindingContextChanged();
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
BindingContext = AssosiatedObject.BindingContext;
}
}
行为转换器:
public class ItemVisibilityEventConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var eventArgs = value as ItemVisibilityEventArgs;
var collection = eventArgs?.Item as System.Collections.ObjectModel.ObservableCollection<object>;
return collection[0];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我的收藏:
public NotifyTask<ObservableRangeCollection<Profile>> Profiles { get; set; }
NotifyTask
与该集合无关。它只是一个包装。
我添加项目的方法:
private async Task OnLoadMore(Profile lastProfile)
{
IsBusy = true;
_pageNumber++;
Profiles.Result.AddRange(await _manager.GetProfilesAsync(_parameters.NextPage()));
IsBusy = false;
}
答案 0 :(得分:2)
您应该使用FlowItemAppearing
/ FlowItemDissappearing
代替ItemAppearing
/ ItemDissappearing
。它提供实际的FlowListView
项目。
在这里添加/删除项目的示例如下:
当项目更新时,这些示例不会在iOS / Android上滚动您的列表。请务必使用最新的nuget包。
XAML:
<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="None" HasUnevenRows="false"
FlowItemTappedCommand="{Binding ItemTappedCommand}" FlowLastTappedItem="{Binding LastTappedItem}"
FlowItemsSource="{Binding Items}" Grid.ColumnSpan="2">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Label HorizontalOptions="Fill" VerticalOptions="Fill"
XAlign="Center" YAlign="Center" Text="{Binding Title}"/>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
查看型号:
public UpdateItemsPageModel()
{
AddCommand = new BaseCommand((arg) =>
{
insertId++;
Items.Insert(10, new SimpleItem() { Title = string.Format("New {0}", insertId) });
});
RemoveCommand = new BaseCommand((arg) =>
{
Items.RemoveAt(10);
});
}
public ObservableCollection<object> Items
{
get { return GetField<ObservableCollection<object>>(); }
set { SetField(value); }
}
答案 1 :(得分:0)
我在我的情况下找到了解决方法。这是代码,当它工作正常时:
private void OnLoadMore(Profile lastProfile)
{
IsBusy = true;
_pageNumber++;
Device.BeginInvokeOnMainThread(async () =>
{
var newItems = await _manager.GetProfilesAsync(_parameters.NextPage());
Profiles.Result.AddRange(newItems);
});
IsBusy = false;
}
还有一个问题。它没有显示加载指示器。在iOS和Android上。如果我将该方法的其余代码放在主线程中,或者从主线程移动GetProfilesAsync,它将像以前一样跳转。