This repository has been archived by the owner on May 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
ItemsViewAdapter.cs
144 lines (117 loc) · 3.59 KB
/
ItemsViewAdapter.cs
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
142
143
144
using System;
using Android.Content;
using Android.Widget;
using AndroidX.RecyclerView.Widget;
using Object = Java.Lang.Object;
using ViewGroup = Android.Views.ViewGroup;
namespace Xamarin.Forms.Platform.Android
{
public class ItemsViewAdapter<TItemsView, TItemsViewSource> : RecyclerView.Adapter
where TItemsView : ItemsView
where TItemsViewSource : IItemsViewSource
{
protected readonly TItemsView ItemsView;
readonly Func<View, Context, ItemContentView> _createItemContentView;
protected internal TItemsViewSource ItemsSource;
bool _disposed;
bool _usingItemTemplate = false;
protected internal ItemsViewAdapter(TItemsView itemsView, Func<View, Context, ItemContentView> createItemContentView = null)
{
ItemsView = itemsView ?? throw new ArgumentNullException(nameof(itemsView));
UpdateUsingItemTemplate();
ItemsView.PropertyChanged += ItemsViewPropertyChanged;
_createItemContentView = createItemContentView;
ItemsSource = CreateItemsSource();
if (_createItemContentView == null)
{
_createItemContentView = (view, context) => new ItemContentView(context);
}
}
protected virtual TItemsViewSource CreateItemsSource()
{
return (TItemsViewSource)ItemsSourceFactory.Create(ItemsView, this);
}
protected virtual void ItemsViewPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs property)
{
if (property.Is(Xamarin.Forms.ItemsView.ItemsSourceProperty))
{
UpdateItemsSource();
}
else if (property.Is(Xamarin.Forms.ItemsView.ItemTemplateProperty))
{
UpdateUsingItemTemplate();
}
}
public override void OnViewRecycled(Object holder)
{
if (holder is TemplatedItemViewHolder templatedItemViewHolder)
{
templatedItemViewHolder.Recycle(ItemsView);
}
base.OnViewRecycled(holder);
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
switch (holder)
{
case TextViewHolder textViewHolder:
textViewHolder.TextView.Text = ItemsSource.GetItem(position).ToString();
break;
case TemplatedItemViewHolder templatedItemViewHolder:
BindTemplatedItemViewHolder(templatedItemViewHolder, ItemsSource.GetItem(position));
break;
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
var context = parent.Context;
if (viewType == ItemViewType.TextItem)
{
var view = new TextView(context);
return new TextViewHolder(view);
}
var itemContentView = _createItemContentView.Invoke(ItemsView, context);
return new TemplatedItemViewHolder(itemContentView, ItemsView.ItemTemplate);
}
public override int ItemCount => ItemsSource.Count;
public override int GetItemViewType(int position)
{
if (_usingItemTemplate)
{
return ItemViewType.TemplatedItem;
}
// No template, just use the Text view
return ItemViewType.TextItem;
}
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
ItemsSource?.Dispose();
ItemsView.PropertyChanged -= ItemsViewPropertyChanged;
}
_disposed = true;
base.Dispose(disposing);
}
}
public virtual int GetPositionForItem(object item)
{
return ItemsSource.GetPosition(item);
}
protected virtual void BindTemplatedItemViewHolder(TemplatedItemViewHolder templatedItemViewHolder, object context)
{
templatedItemViewHolder.Bind(context, ItemsView);
}
void UpdateItemsSource()
{
ItemsSource?.Dispose();
ItemsSource = CreateItemsSource();
}
void UpdateUsingItemTemplate()
{
_usingItemTemplate = ItemsView.ItemTemplate != null;
}
}
}