diff --git a/CarouselViewChallenge/CarouselViewChallenge.Android/CarouselViewChallenge.Android.csproj b/CarouselViewChallenge/CarouselViewChallenge.Android/CarouselViewChallenge.Android.csproj
index 1e33499..945a2da 100644
--- a/CarouselViewChallenge/CarouselViewChallenge.Android/CarouselViewChallenge.Android.csproj
+++ b/CarouselViewChallenge/CarouselViewChallenge.Android/CarouselViewChallenge.Android.csproj
@@ -53,9 +53,18 @@
+
+ 1.68.0
+
+
+ 2.4.11.982
+
+
+ 2.4.11.982
+
-
-
+
+
@@ -101,4 +110,4 @@
-
+
\ No newline at end of file
diff --git a/CarouselViewChallenge/CarouselViewChallenge.Android/MainActivity.cs b/CarouselViewChallenge/CarouselViewChallenge.Android/MainActivity.cs
index fd4e22a..993ec01 100644
--- a/CarouselViewChallenge/CarouselViewChallenge.Android/MainActivity.cs
+++ b/CarouselViewChallenge/CarouselViewChallenge.Android/MainActivity.cs
@@ -6,6 +6,7 @@
using Android.Views;
using Android.Widget;
using Android.OS;
+using FFImageLoading.Forms.Platform;
namespace CarouselViewChallenge.Droid
{
@@ -20,8 +21,10 @@ protected override void OnCreate(Bundle savedInstanceState)
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");
+ FFImageLoading.Forms.Platform.CachedImageRenderer.Init(enableFastRenderer: true);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
+ CachedImageRenderer.InitImageViewHandler();
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
diff --git a/CarouselViewChallenge/CarouselViewChallenge.iOS/AppDelegate.cs b/CarouselViewChallenge/CarouselViewChallenge.iOS/AppDelegate.cs
index 949500f..562057c 100644
--- a/CarouselViewChallenge/CarouselViewChallenge.iOS/AppDelegate.cs
+++ b/CarouselViewChallenge/CarouselViewChallenge.iOS/AppDelegate.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
-
+using FFImageLoading.Forms.Platform;
using Foundation;
using UIKit;
@@ -23,7 +23,9 @@ public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsAppli
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");
+ FFImageLoading.Forms.Platform.CachedImageRenderer.Init();
global::Xamarin.Forms.Forms.Init();
+ CachedImageRenderer.InitImageSourceHandler();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
diff --git a/CarouselViewChallenge/CarouselViewChallenge.iOS/CarouselViewChallenge.iOS.csproj b/CarouselViewChallenge/CarouselViewChallenge.iOS/CarouselViewChallenge.iOS.csproj
index 6241d2c..7a6d802 100644
--- a/CarouselViewChallenge/CarouselViewChallenge.iOS/CarouselViewChallenge.iOS.csproj
+++ b/CarouselViewChallenge/CarouselViewChallenge.iOS/CarouselViewChallenge.iOS.csproj
@@ -129,8 +129,17 @@
+
+ 1.68.0
+
+
+ 2.4.11.982
+
+
+ 2.4.11.982
+
-
+
@@ -139,4 +148,4 @@
CarouselViewChallenge
-
+
\ No newline at end of file
diff --git a/CarouselViewChallenge/CarouselViewChallenge/App.xaml b/CarouselViewChallenge/CarouselViewChallenge/App.xaml
index f3469f1..b82ae9d 100644
--- a/CarouselViewChallenge/CarouselViewChallenge/App.xaml
+++ b/CarouselViewChallenge/CarouselViewChallenge/App.xaml
@@ -6,5 +6,17 @@
mc:Ignorable="d"
x:Class="CarouselViewChallenge.App">
+
+
+ #E8D6CB
+ #6683A9
+ #192E4A
+
+
+
+ #77abb7
+ #476d7c
+ #1d3e53
+
\ No newline at end of file
diff --git a/CarouselViewChallenge/CarouselViewChallenge/CarouselViewChallenge.csproj b/CarouselViewChallenge/CarouselViewChallenge/CarouselViewChallenge.csproj
index a58ec88..51b00ab 100644
--- a/CarouselViewChallenge/CarouselViewChallenge/CarouselViewChallenge.csproj
+++ b/CarouselViewChallenge/CarouselViewChallenge/CarouselViewChallenge.csproj
@@ -6,8 +6,11 @@
+
+
+
-
+
diff --git a/CarouselViewChallenge/CarouselViewChallenge/Models/Sensor.cs b/CarouselViewChallenge/CarouselViewChallenge/Models/Sensor.cs
new file mode 100644
index 0000000..8522229
--- /dev/null
+++ b/CarouselViewChallenge/CarouselViewChallenge/Models/Sensor.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CarouselViewChallenge.Models
+{
+ public class Sensor
+ {
+
+ public int Sensor_ID { get; set; }
+
+ public string Name { get; set; }
+
+ public double Temperature { get; set; }
+
+ public double AvgTemperature { get; set; }
+
+ public string imageSrc { get; set; }
+
+
+ public string TemperatureFormatted { get {
+ return "Current: "+Temperature + "\xB0"+"F";
+
+ } }
+ public string AvgTemperatureFormatted
+ {
+ get
+ {
+ return "Avg: "+AvgTemperature + "\xB0"+"F";
+ }
+ }
+
+ }
+}
diff --git a/CarouselViewChallenge/CarouselViewChallenge/ViewModels/BaseViewModel.cs b/CarouselViewChallenge/CarouselViewChallenge/ViewModels/BaseViewModel.cs
new file mode 100644
index 0000000..a0073f5
--- /dev/null
+++ b/CarouselViewChallenge/CarouselViewChallenge/ViewModels/BaseViewModel.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+
+namespace CarouselViewChallenge.ViewModels
+{
+ public class BaseViewModel : INotifyPropertyChanged
+ {
+ // public IDataStore- DataStore => DependencyService.Get>() ?? new MockDataStore();
+ public event PropertyChangedEventHandler PropertyChanged;
+ string _propTitle = string.Empty;
+ bool _propIsBusy;
+ bool isBusy = false;
+ public bool IsBusy
+ {
+ get { return _propIsBusy; }
+ set { SetProperty(ref _propIsBusy, value, "IsBusy"); }
+ }
+
+ string title = string.Empty;
+ public string Title
+ {
+ get { return _propTitle; }
+ set { SetProperty(ref _propTitle, value, "Title"); }
+ }
+
+ protected void SetProperty(ref T store, T value, string propName, Action onChanged = null)
+ {
+ if (EqualityComparer.Default.Equals(store, value))
+ return;
+ store = value;
+ if (onChanged != null)
+ onChanged();
+ OnPropertyChanged(propName);
+ }
+
+ //#region INotifyPropertyChanged
+ //public event PropertyChangedEventHandler PropertyChanged;
+ public void OnPropertyChanged(string propName)
+ {
+ if (PropertyChanged == null)
+ return;
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ //#endregion
+ }
+}
diff --git a/CarouselViewChallenge/CarouselViewChallenge/ViewModels/CarouselViewChallengePageViewModel.cs b/CarouselViewChallenge/CarouselViewChallenge/ViewModels/CarouselViewChallengePageViewModel.cs
new file mode 100644
index 0000000..f9dc25b
--- /dev/null
+++ b/CarouselViewChallenge/CarouselViewChallenge/ViewModels/CarouselViewChallengePageViewModel.cs
@@ -0,0 +1,49 @@
+using CarouselViewChallenge.Models;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+
+namespace CarouselViewChallenge.ViewModels
+{
+ public class CarouselViewChallengePageViewModel:BaseViewModel
+ {
+ Dictionary sensorNameLocations;
+ ObservableCollection sensors = new ObservableCollection();
+
+ public CarouselViewChallengePageViewModel() {
+
+
+ sensorNameLocations = new Dictionary();
+ sensorNameLocations.Add("Bar", "https://www.beveragefactory.com/images/MO24BNS1RS-built-in010516144751.jpg");
+ sensorNameLocations.Add("Kitchen", "https://cdn-image.realsimple.com/sites/default/files/1537981754/matte-appliances-trend-kitchen.JPG");
+ sensorNameLocations.Add("Bedroom", "https://www.ikea.com/ms/media/rooms/20201/bedroom/20201_rmbe05a/20201_rmbe05a_01_thumb_PH163122.jpg");
+ sensorNameLocations.Add("Garage", "https://www.residencestyle.com/wp-content/uploads/2019/06/Garage.jpg");
+ sensorNameLocations.Add("PC", "https://i.pinimg.com/originals/75/79/ee/7579ee363b374c6c02455b98a6eeaa6d.jpg");
+ sensorNameLocations.Add("Attic", "https://49op3q1oapcpd3h2q1ys9f81-wpengine.netdna-ssl.com/wp-content/uploads/2017/08/attic-2416396_1920.jpg");
+ sensorNameLocations.Add("Monkey Habitat", "https://pixfeeds.com/images/animals/monkeys/1280-669297382-sri-lankan-monkeys-at-yala-national-park.jpg");
+ setupFakeData();
+ }
+
+
+
+
+
+ private void setupFakeData()
+ {
+ Random r = new Random();
+ foreach (string s in sensorNameLocations.Keys) {
+ var temp = Math.Round(r.Next(30, 104) + r.NextDouble(),2);
+ Sensors.Add(new Sensor(){ Sensor_ID = 0,Name=s+" Sensor", Temperature=temp, AvgTemperature=temp+r.Next(-5,5), imageSrc= sensorNameLocations[s] });
+
+ }
+ }
+
+
+ public ObservableCollection Sensors
+ {
+ get { return sensors; }
+ set { SetProperty(ref sensors, value, "Sensors"); }
+ }
+ }
+}
diff --git a/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml b/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml
index 1a7cc0d..04a7f86 100644
--- a/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml
+++ b/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml
@@ -3,11 +3,129 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:CarouselViewChallenge.ViewModels"
+ xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
+ xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
+ xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
mc:Ignorable="d"
x:Class="CarouselViewChallenge.Views.CarouselViewChallengePage">
+
+
+
+
+
+
+
+ mountain_dark
+
+ #FFFFFF
+ #768ea0
+ #d2d7dd
+ #ffa318
+ #FFFFFF
+ #FFFFFF
+ #ffffff
+
+
+ #E8D6CB
+ #6683A9
+ #192E4A
+
+ #7A89B1
+ #FB7D80
+
+
+
+ LightGray
+ Black
+ Black
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml.cs b/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml.cs
index 38f2e9f..17fe3cb 100644
--- a/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml.cs
+++ b/CarouselViewChallenge/CarouselViewChallenge/Views/CarouselViewChallengePage.xaml.cs
@@ -1,4 +1,6 @@
-using System;
+using SkiaSharp;
+using SkiaSharp.Views.Forms;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -16,5 +18,62 @@ public CarouselViewChallengePage()
{
InitializeComponent();
}
+
+ SKPaint backgroundBrush = new SKPaint()
+ {
+ Style = SKPaintStyle.Fill,
+ Color = Color.Red.ToSKColor()
+ };
+
+ private void BackgroundGradient_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
+ {
+ SKImageInfo info = e.Info;
+ SKSurface surface = e.Surface;
+ SKCanvas canvas = surface.Canvas;
+
+ canvas.Clear();
+
+ // get the brush based on the theme
+ SKColor gradientStart = ((Color)Application.Current.Resources["BackgroundGradientStartColor"]).ToSKColor();
+ SKColor gradientMid = ((Color)Application.Current.Resources["BackgroundGradientMidColor"]).ToSKColor();
+ SKColor gradientEnd = ((Color)Application.Current.Resources["BackgroundGradientEndColor"]).ToSKColor();
+
+ // gradient background with 3 colors
+ backgroundBrush.Shader = SKShader.CreateRadialGradient(
+ new SKPoint(0, info.Height * .8f),
+ info.Height * .8f,
+ new SKColor[] { gradientStart, gradientMid, gradientEnd },
+ new float[] { 0, .5f, 1 },
+ SKShaderTileMode.Clamp);
+
+ SKRect backgroundBounds = new SKRect(0, 0, info.Width, info.Height);
+ canvas.DrawRect(backgroundBounds, backgroundBrush);
+ }
+
+
+ private void CarouselGradient_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e)
+ {
+ SKImageInfo info = e.Info;
+ SKSurface surface = e.Surface;
+ SKCanvas canvas = surface.Canvas;
+
+ canvas.Clear();
+
+ // get the brush based on the theme
+ SKColor gradientStart = ((Color)Application.Current.Resources["CarouselGradientStartColor"]).ToSKColor();
+ SKColor gradientMid = ((Color)Application.Current.Resources["CarouselGradientMidColor"]).ToSKColor();
+ SKColor gradientEnd = ((Color)Application.Current.Resources["CarouselGradientEndColor"]).ToSKColor();
+
+ // gradient background with 3 colors
+ backgroundBrush.Shader = SKShader.CreateLinearGradient(
+ new SKPoint(0, 0),
+ new SKPoint(info.Width, info.Height),
+ new SKColor[] { gradientStart, gradientMid, gradientEnd },
+ new float[] { 0, .5f, 1 },
+ SKShaderTileMode.Clamp);
+
+ SKRect backgroundBounds = new SKRect(0, 0, info.Width, info.Height);
+ canvas.DrawRoundRect(new SKRoundRect(backgroundBounds, 60, 60), backgroundBrush);
+ }
}
}
\ No newline at end of file