-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathBindableFragmentPagerAdapter.cs
More file actions
122 lines (101 loc) · 3.93 KB
/
BindableFragmentPagerAdapter.cs
File metadata and controls
122 lines (101 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using AndroidX.Fragment.App;
using BMM.Core.ViewModels;
using BMM.UI.Droid.Application.Extensions;
using BMM.UI.Droid.Application.Helpers;
using Microsoft.Extensions.Logging;
using MvvmCross;
using MvvmCross.Binding;
using MvvmCross.Logging;
using MvvmCross.Views;
using MvvmCross.WeakSubscription;
using Fragment = AndroidX.Fragment.App.Fragment;
using FragmentManager = AndroidX.Fragment.App.FragmentManager;
using Object = Java.Lang.Object;
namespace BMM.UI.Droid.Application.Adapters
{
public class BindableFragmentPagerAdapter <TViewModel>: FragmentPagerAdapter
where TViewModel : class
{
private readonly FragmentManager _fragmentManager;
private readonly Func<TViewModel, BmmViewPagerFragmentInfo> _createViewAction;
private IEnumerable<TViewModel> _itemsSource;
private MvxNotifyCollectionChangedEventSubscription _subscription;
public BindableFragmentPagerAdapter(FragmentManager fragmentManager,
Func<TViewModel, BmmViewPagerFragmentInfo> createViewAction)
: base(fragmentManager, BehaviorResumeOnlyCurrentFragment)
{
_fragmentManager = fragmentManager;
_createViewAction = createViewAction;
}
public override int GetItemPosition(Object value) => PositionNone;
public IEnumerable<BmmViewPagerFragmentInfo> Fragments { get; private set; }
public IEnumerable<TViewModel> ItemsSource
{
get => _itemsSource;
set => SetItemsSource(value);
}
public override Fragment GetItem(int position)
{
var fragInfo = Fragments.ElementAt(position);
if (fragInfo.CachedFragment == null)
{
fragInfo.CachedFragment = _fragmentManager.Instantiate(fragInfo);
var fragmentAsView = (IMvxView)fragInfo.CachedFragment;
fragmentAsView.ViewModel = fragInfo.ViewModel;
}
return fragInfo.CachedFragment;
}
protected virtual void SetItemsSource(IEnumerable<TViewModel> value)
{
if (ReferenceEquals(_itemsSource, value))
{
return;
}
_subscription?.Dispose();
_subscription = null;
_itemsSource = value;
if (_itemsSource != null && !(_itemsSource is IList))
{
MvxBindingLog.Instance?.LogWarning("Binding to IEnumerable rather than IList - this can be inefficient, especially for large lists");
}
var newObservable = _itemsSource as INotifyCollectionChanged;
if (newObservable != null)
{
_subscription = newObservable.WeakSubscribe(OnItemsSourceCollectionChanged);
}
BuildFragments();
NotifyDataSetChanged();
}
private void BuildFragments()
{
var fragments = new List<BmmViewPagerFragmentInfo>();
foreach (var item in ItemsSource)
{
BmmViewPagerFragmentInfo toAdd;
if (Fragments != null
&& (toAdd = Fragments.FirstOrDefault(x => Equals(x.ViewModel, item))) != null
&& toAdd.CachedFragment != null)
{
fragments.Add(toAdd);
}
else
{
toAdd = _createViewAction.Invoke((item as TViewModel));
fragments.Add(toAdd);
}
}
Fragments = fragments;
}
private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
BuildFragments();
NotifyDataSetChanged();
}
public override int Count => ItemsSource?.Count() ?? 0;
}
}