forked from reactiveui/ReactiveUI
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReactivePagerAdapter.cs
More file actions
141 lines (123 loc) · 5.32 KB
/
ReactivePagerAdapter.cs
File metadata and controls
141 lines (123 loc) · 5.32 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Android.Views;
using AndroidX.ViewPager.Widget;
using DynamicData;
using DynamicData.Binding;
using Splat;
using Object = Java.Lang.Object;
namespace ReactiveUI.AndroidX
{
/// <summary>
/// ReactivePagerAdapter is a PagerAdapter that will interface with a
/// Observable change set, in a similar fashion to ReactiveTableViewSource.
/// </summary>
/// <typeparam name="TViewModel">The view model type.</typeparam>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")]
public class ReactivePagerAdapter<TViewModel> : PagerAdapter, IEnableLogger
where TViewModel : class
{
private readonly SourceList<TViewModel> _list;
private readonly Func<TViewModel, ViewGroup, View> _viewCreator;
private readonly Action<TViewModel, View> _viewInitializer;
private readonly IDisposable _inner;
/// <summary>
/// Initializes a new instance of the <see cref="ReactivePagerAdapter{TViewModel}"/> class.
/// </summary>
/// <param name="changeSet">The change set to page.</param>
/// <param name="viewCreator">A function which will create the view.</param>
/// <param name="viewInitializer">A action which will initialize a view.</param>
public ReactivePagerAdapter(
IObservable<IChangeSet<TViewModel>> changeSet,
Func<TViewModel, ViewGroup, View> viewCreator,
Action<TViewModel, View> viewInitializer = null)
{
_list = new SourceList<TViewModel>(changeSet);
_viewCreator = viewCreator;
_viewInitializer = viewInitializer;
_inner = _list.Connect().Subscribe(_ => NotifyDataSetChanged());
}
/// <inheritdoc/>
public override int Count => _list.Count;
/// <inheritdoc/>
public override bool IsViewFromObject(View view, Object @object)
{
return (View)@object == view;
}
/// <inheritdoc/>
public override Object InstantiateItem(ViewGroup container, int position)
{
var data = _list.Items.ElementAt(position);
// NB: PagerAdapter does not recycle itself.
var theView = _viewCreator(data, container);
var ivf = theView.GetViewHost() as IViewFor<TViewModel>;
if (ivf != null)
{
ivf.ViewModel = data;
}
_viewInitializer?.Invoke(data, theView);
container.AddView(theView, 0);
return theView;
}
/// <inheritdoc/>
public override void DestroyItem(ViewGroup container, int position, Object item)
{
if (container == null)
{
throw new ArgumentNullException(nameof(container));
}
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
if (!(item is View view))
{
throw new ArgumentException("Item must be of type View", nameof(item));
}
container.RemoveView(view);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
if (disposing)
{
_inner?.Dispose();
_list?.Dispose();
}
base.Dispose(disposing);
}
}
/// <summary>
/// ReactivePagerAdapter is a PagerAdapter that will interface with a
/// Observable change set, in a similar fashion to ReactiveTableViewSource.
/// </summary>
/// <typeparam name="TViewModel">The view model type.</typeparam>
/// <typeparam name="TCollection">The type of collection.</typeparam>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleType", Justification = "Classes with the same class names within.")]
public class ReactivePagerAdapter<TViewModel, TCollection> : ReactivePagerAdapter<TViewModel>
where TViewModel : class
where TCollection : INotifyCollectionChanged, IEnumerable<TViewModel>
{
/// <summary>
/// Initializes a new instance of the <see cref="ReactivePagerAdapter{TViewModel, TCollection}"/> class.
/// </summary>
/// <param name="collection">The collection to page.</param>
/// <param name="viewCreator">The function which will create the view.</param>
/// <param name="viewInitializer">A action which will initialize the view.</param>
public ReactivePagerAdapter(
TCollection collection,
Func<TViewModel, ViewGroup, View> viewCreator,
Action<TViewModel, View> viewInitializer = null)
: base(collection.ToObservableChangeSet<TCollection, TViewModel>(), viewCreator, viewInitializer)
{
}
}
#pragma warning restore SA1600 // Elements should be documented
}