3

ObservableRangeCollectionのヘルプを使用して無限のスクロールを持つリストビューが作成されました。それはAndroidでうまくいきますが、iOSでは新しいアイテムを追加するたびに起動します。改ページは動作で行われます。 ListViewはFlowListViewです。ここ はXAMLです:iOSの無限リストビューを最初のアイテムにジャンプしてから再表示

... 
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がnothiを持っていますコレクションとは関係ありません。それは単なるラッパーです。

私はアイテムを追加する方法:

private async Task OnLoadMore(Profile lastProfile) 
     { 
      IsBusy = true; 
      _pageNumber++; 
      Profiles.Result.AddRange(await _manager.GetProfilesAsync(_parameters.NextPage())); 
      IsBusy = false; 
     } 
+0

「FlowListView」とは何ですか? Xamarin.Formsの一部ではありません。 – Krumelur

+0

@Krumelurここにあります:https://github.com/daniel-luberda/DLToolkit.Forms.Controls/tree/master/FlowListView –

+0

そこに問題を提起することを検討する必要があります。 https://github.com/daniel-luberda/DLToolkit.Forms.Controls/issues – Krumelur

答えて

2

これらの例は、iOS上であなたのリストをスクロールしません/アイテムが更新されるときのAndroid最新のナゲットパッケージを使用してください。

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

私はflow listview nugetをあなたが言ったような最後の安定した置き換えられたイベントに更新し、insertで要素を追加しようとしました。そして、私の観察があります: - あなたのサンプルのような1つのアイテムを追加すると動作しますが、このアイテムがダウンロードされない場合、このエラーでクラッシュします:MonoTouch.Foundation.MonoTouchException:Objective-C例外がスローされます。名前:NSRangeException理由:*** - [__ NSArrayM objectAtIndex:]: サイクルで挿入するかaddまたはaddRangeを使って項目を追加する場合、以前と同じになります。 –

+0

しかし、次のページが表示される前に指が表示されていれば(エミュレータ)、それが動作することに気付きました。リフレッシュインジケータがなく、無音状態で項目を追加するだけです。しかし、インジケータがあると、最初のページにジャンプします。 Androidではすべてが魅力的です。標識付き、ジャンプなし、コード付き。 –

+0

複製して私に送ってもらえますか?私の電子メールは私のgithubアカウントページにあります。私はバグの場合、これを修正しようとします:) –

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を移動したりすると、前と同じようにジャンプします。

関連する問題