-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathImageCarousel.cs
132 lines (103 loc) · 3.94 KB
/
ImageCarousel.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
using System;
using Xamarin.Forms;
using System.Collections.Generic;
namespace XamarinDevDaysDemo
{
public class ImageCarousel : AbsoluteLayout
{
//The Bindable Images property, if MVVM/binding context is desired
public static readonly BindableProperty ImagesProperty = BindableProperty.Create<ImageCarousel, IEnumerable<FileImageSource>> (p => p.Images, default(IEnumerable<FileImageSource>));
public IEnumerable<FileImageSource> Images {
get { return (IEnumerable<FileImageSource>)GetValue (ImagesProperty); }
set { SetValue (ImagesProperty, value); }
}
//Our interal list - we'll maintain this when the above Images collection is modified and use this to do indexing, etc. that can't be done on an IEnumerable
List<Image> images;
List<Image> ImageList {
get {
if (images == null) {
images = new List<Image> ();
}
return images;
}
}
public Image CurrentImage { get; private set; }
public ImageCarousel ()
{
}
public ImageCarousel (IEnumerable<FileImageSource> images)
{
//setting this triggers OnPropertyChanged below
Images = images;
}
void addImagesAsChildren ()
{
Children.Clear ();
//take the current list of Images and add them as children... this will in turn populate ImageList via OnChildAdded below
var point = Point.Zero;
foreach (var imageSource in Images) {
var image = new Image {
Source = imageSource
};
this.Children.Add (image, new Rectangle (point, new Size (1, 1)), AbsoluteLayoutFlags.SizeProportional);
point = new Point (point.X + image.Width, 0);
}
}
protected override void LayoutChildren (double x, double y, double width, double height)
{
base.LayoutChildren (x, y, width, height);
//fix layout issues caused by base behavior, make sure these things are in the right place before swiping begins
var point = Point.Zero;
foreach (var image in ImageList) {
image.Layout (new Rectangle (point, image.Bounds.Size));
point = new Point (point.X + image.Width, 0);
}
}
protected override void OnPropertyChanged (string propertyName = null)
{
base.OnPropertyChanged (propertyName);
//if the Images property has changed, clear our ImageList of images and add all the new images as children
if (propertyName == ImagesProperty.PropertyName) {
ImageList.Clear ();
CurrentImage = null;
addImagesAsChildren ();
}
}
protected override void OnChildAdded (Element child)
{
base.OnChildAdded (child);
//each time a child Image is added, add it to the ImageList
if (child is Image) {
ImageList.Add ((Image)child);
//set a CurrentImage if we don't already have one
if (CurrentImage == null) {
CurrentImage = (Image)child;
}
}
}
public void OnSwipeLeft ()
{
var imageNumber = ImageList.IndexOf (CurrentImage);
var nextNumber = imageNumber == ImageList.Count - 1 ? 0 : imageNumber + 1;
var nextImage = ImageList [nextNumber];
//make sure this image is in position to be animated in
nextImage.Layout (new Rectangle (new Point (CurrentImage.Width, 0), CurrentImage.Bounds.Size));
var current = CurrentImage;
current.LayoutTo (new Rectangle (-CurrentImage.Width, 0, CurrentImage.Width, CurrentImage.Height));
CurrentImage = nextImage;
nextImage.LayoutTo (new Rectangle (0, 0, CurrentImage.Width, CurrentImage.Height));
}
public void OnSwipeRight ()
{
var imageNumber = ImageList.IndexOf (CurrentImage);
var nextNumber = imageNumber == 0 ? ImageList.Count - 1 : imageNumber - 1;
var nextImage = ImageList [nextNumber];
//make sure this image is in position to be animated in
nextImage.Layout (new Rectangle (new Point (-CurrentImage.Width, 0), CurrentImage.Bounds.Size));
var current = CurrentImage;
current.LayoutTo (new Rectangle (CurrentImage.Width, 0, CurrentImage.Width, CurrentImage.Height));
CurrentImage = nextImage;
nextImage.LayoutTo (new Rectangle (0, 0, CurrentImage.Width, CurrentImage.Height));
}
}
}