/
StaggeredCollectionViewRenderer.cs
110 lines (93 loc) · 3.22 KB
/
StaggeredCollectionViewRenderer.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
using System;
using Android.Content;
#if __ANDROID_29__
using AndroidX.AppCompat.Widget;
using AndroidX.RecyclerView.Widget;
#else
using Android.Support.V7.Widget;
#endif
using Xamarin.Forms;
using Xamarin.Forms.ControlGallery.Android;
using Xamarin.Forms.Controls.GalleryPages.CollectionViewGalleries.AlternateLayoutGalleries;
using Xamarin.Forms.Platform.Android;
using ARect = Android.Graphics.Rect;
using AView = Android.Views.View;
[assembly: ExportRenderer(typeof(StaggeredCollectionView), typeof(StaggeredCollectionViewRenderer))]
namespace Xamarin.Forms.ControlGallery.Android
{
public class StaggeredCollectionViewRenderer : CollectionViewRenderer
{
public StaggeredCollectionViewRenderer(Context context) : base(context) { }
protected override LayoutManager SelectLayoutManager(IItemsLayout layoutSpecification)
{
if (layoutSpecification is StaggeredGridItemsLayout staggeredGridLayout)
{
var manager = new StaggeredGridLayoutManager(staggeredGridLayout.Span,
staggeredGridLayout.Orientation == ItemsLayoutOrientation.Horizontal
? LinearLayoutManager.Horizontal
: LinearLayoutManager.Vertical);
manager.GapStrategy = StaggeredGridLayoutManager.GapHandlingNone;
return manager;
}
return base.SelectLayoutManager(layoutSpecification);
}
protected override ItemDecoration CreateSpacingDecoration(IItemsLayout itemsLayout)
{
return new SpacingItemDecoration(itemsLayout as StaggeredGridItemsLayout);
}
}
public class SpacingItemDecoration : RecyclerView.ItemDecoration
{
ItemsLayoutOrientation _orientation;
double _verticalSpacing;
double _adjustedVerticalSpacing = -1;
double _horizontalSpacing;
double _adjustedHorizontalSpacing = -1;
int _span = 1;
public SpacingItemDecoration(StaggeredGridItemsLayout itemsLayout)
{
if (itemsLayout == null)
{
throw new ArgumentNullException(nameof(itemsLayout));
}
switch (itemsLayout)
{
case StaggeredGridItemsLayout gridItemsLayout:
_orientation = gridItemsLayout.Orientation;
_horizontalSpacing = gridItemsLayout.HorizontalItemSpacing;
_verticalSpacing = gridItemsLayout.VerticalItemSpacing;
_span = gridItemsLayout.Span;
break;
}
}
public override void GetItemOffsets(ARect outRect, AView view, RecyclerView parent, RecyclerView.State state)
{
base.GetItemOffsets(outRect, view, parent, state);
var position = parent.GetChildAdapterPosition(view);
if (_adjustedVerticalSpacing == -1)
{
_adjustedVerticalSpacing = parent.Context.ToPixels(_verticalSpacing);
}
if (_adjustedHorizontalSpacing == -1)
{
_adjustedHorizontalSpacing = parent.Context.ToPixels(_horizontalSpacing);
}
var spanIndex = 0;
var layoutParameters = view.LayoutParameters as StaggeredGridLayoutManager.LayoutParams;
if (layoutParameters != null)
{
spanIndex = layoutParameters.SpanIndex;
}
if (_orientation == ItemsLayoutOrientation.Vertical)
{
outRect.Left = spanIndex == 0 ? 0 : (int)_adjustedHorizontalSpacing;
outRect.Top = position < _span ? 0 : (int)_adjustedVerticalSpacing;
}
else
{
outRect.Left = position < _span ? 0 : (int)_adjustedHorizontalSpacing;
outRect.Top = spanIndex == 0 ? 0 : (int)_adjustedVerticalSpacing;
}
}
}
}