diff --git a/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/MainPage.xaml b/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/MainPage.xaml
index ee2dfe0..98c5849 100644
--- a/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/MainPage.xaml
+++ b/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/MainPage.xaml
@@ -50,6 +50,7 @@
ExpandedPercentage="{Binding ExpandedPercentage}"
IsExpanded="{Binding IsExpanded}"
IsVisible="{Binding IsVisible}"
+ LockStates="{Binding LockStates}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=1,
diff --git a/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/ViewModel/MainPageViewModel.cs b/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/ViewModel/MainPageViewModel.cs
index 6b0f18a..946c6a6 100644
--- a/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/ViewModel/MainPageViewModel.cs
+++ b/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/ViewModel/MainPageViewModel.cs
@@ -38,8 +38,12 @@ public class MainPageViewModel : ObservableObject
///
/// The bottom drawer lock states
+ ///
+ /// Note: [alex-d] works incorrectly when more than 3 values
+ /// private double[] _LockStates = new double[] { 0, .30, 0.6, 0.95 };
///
private double[] _LockStates = new double[] { 0, .50, 0.75 };
+
#endregion
diff --git a/Xam.Plugin.SimpleBottomDrawer/BottomDrawer.cs b/Xam.Plugin.SimpleBottomDrawer/BottomDrawer.cs
index f72b3cb..f2f2aab 100644
--- a/Xam.Plugin.SimpleBottomDrawer/BottomDrawer.cs
+++ b/Xam.Plugin.SimpleBottomDrawer/BottomDrawer.cs
@@ -104,7 +104,23 @@ public bool IsExpanded
public double ExpandedPercentage
{
get => (double)GetValue(ExpandedPercentageProperty);
- set => SetValue(ExpandedPercentageProperty, value);
+ set
+ {
+#if DEBUG
+ if (value > 0.8)
+ {
+ // > 360.0 / 640.0
+ // 0.5625
+ // ---
+ // > 0.5625 + (1 - 0.5625) / 2
+ // 0.78125
+ // -
+ System.Console.WriteLine("[BottomDrawer] debug drag to top");
+ }
+#endif
+
+ SetValue(ExpandedPercentageProperty, value);
+ }
}
#endregion
@@ -115,7 +131,10 @@ public double ExpandedPercentage
///
/// Make sure we collapse the view on orientation change
///
- protected override void OnSizeAllocated(double width, double height)
+ protected override void OnSizeAllocated(
+ double width
+ , double height
+ )
{
base.OnSizeAllocated(width, height);
if (width != _width || height != _height)
@@ -137,16 +156,29 @@ protected override void OnSizeAllocated(double width, double height)
/// The bindable object
/// The old value
/// The new value
- private static void IsExpandedPropertyChanged(BindableObject bindable, object o, object n)
+ private static void IsExpandedPropertyChanged(
+ BindableObject bindable
+ , object o
+ , object n)
{
if (n is bool isExpanded && bindable is BottomDrawer drawer)
{
if (!drawer.isDragging)
{
if (!isExpanded)
+ {
+#if DEBUG
+ System.Console.WriteLine("[BottomDrawer] IsExpandedPropertyChanged() ==> Dismiss()");
+#endif
drawer.Dismiss();
+ }
else
+ {
+#if DEBUG
+ System.Console.WriteLine("[BottomDrawer] IsExpandedPropertyChanged() ==> Open()");
+#endif
drawer.Open();
+ }
}
}
}
@@ -157,17 +189,46 @@ private static void IsExpandedPropertyChanged(BindableObject bindable, object o,
/// The bindable object
/// The old value
/// The new value
- private static void ExpandedPercentageChanged(BindableObject bindable, object o, object n)
+ private static void ExpandedPercentageChanged(
+ BindableObject bindable
+ , object o
+ , object n)
{
if (n is double expandValue && bindable is BottomDrawer drawer)
{
if (!drawer.isDragging)
{
- var finalTranslation = Math.Max(Math.Min(0, -1000), -Math.Abs(drawer.getProportionCoordinate(expandValue)));
+ double proportionY = drawer.getProportionCoordinate(expandValue);
+
+ var finalTranslation =
+ Math.Max(
+ Math.Min(0, -1000)
+ , -Math.Abs(proportionY)
+ );
+
+#if DEBUG
+ System.Console.WriteLine(
+ $"[BottomDrawer] ExpandedPercentageChanged() ==> proportionY=={proportionY} | finalTranslation=={finalTranslation}");
+#endif
+
if (expandValue < 0)
- drawer.TranslateTo(drawer.X, finalTranslation, 250, Easing.SpringIn);
+ {
+ drawer.TranslateTo(
+ x: drawer.X
+ , y: finalTranslation
+ , length: 250
+ , easing: Easing.SpringIn
+ );
+ }
else
- drawer.TranslateTo(drawer.X, finalTranslation, 250, Easing.SpringOut);
+ {
+ drawer.TranslateTo(
+ x: drawer.X
+ , y: finalTranslation
+ , length: 250
+ , easing: Easing.SpringOut
+ );
+ }
}
}
}
@@ -175,49 +236,152 @@ private static void ExpandedPercentageChanged(BindableObject bindable, object o,
///
/// On pan gesture changed
///
- private void OnPanChanged(object sender, PanUpdatedEventArgs e)
+ private void OnPanChanged(
+ object sender
+ , PanUpdatedEventArgs e
+ )
{
+ double Y =
+ (Device.RuntimePlatform == Device.Android
+ ? this.TranslationY // Frame.TranslationY
+ : this.translationYStart)
+ + e.TotalY;
+ double tmpExpandedPercentage = GetPropertionDistance(Y);
+
+
switch (e.StatusType)
{
case GestureStatus.Running:
isDragging = true;
- var Y = (Device.RuntimePlatform == Device.Android ? this.TranslationY : translationYStart) + e.TotalY;
+
+
// Translate and ensure we don't y + e.TotalY pan beyond the wrapped user interface element bounds.
- var translateY = Math.Max(Math.Min(0, Y), -Math.Abs((Height * .25) - Height));
- this.TranslateTo(this.X, translateY, 1);
- ExpandedPercentage = GetPropertionDistance(Y);
+ var translateY =
+ Math.Max(
+ Math.Min(0, Y)
+ , -Math.Abs((Height * .25) - Height)
+ );
+
+ this.TranslateTo(x: this.X, y: translateY, length: 1);
+ this.ExpandedPercentage = tmpExpandedPercentage;
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] OnPanChanged() - Running | ExpandedPercentage=={ExpandedPercentage} | translateY=={translateY}");
+#endif
break;
+
case GestureStatus.Completed:
+#if DEBUG
+ System.Console.WriteLine("[BottomDrawer] OnPanChanged() - Completed");
+#endif
+
+ double dragDistanceY1 = e.TotalY + this.TranslationY;
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] OnPanChanged() - call#1 GetClosestLockState({dragDistanceY1})");
+#endif
+ // Note: [alex-d] when calculated value was used, there was an issue of not expanding to full screen
+ // -
+ double tmpLockState = GetClosestLockStatePercentage(this.ExpandedPercentage);
+ double tmpLockStateY = getProportionCoordinate(tmpLockState);
+
// At the end of the event - snap to the closest location
- var finalTranslation = Math.Max(Math.Min(0, -1000), -Math.Abs(getProportionCoordinate(GetClosestLockState(e.TotalY + this.TranslationY))));
+ double finalTranslation =
+ Math.Max(
+ Math.Min(0, -1000)
+ , -Math.Abs(tmpLockStateY)
+ );
// Depending on Swipe Up or Down - change the snapping animation
if (DetectSwipeUp(e))
- this.TranslateTo(this.X, finalTranslation, 250, Easing.SpringIn);
+ {
+#if DEBUG
+ System.Console.WriteLine("[BottomDrawer] OnPanChanged() - DetectSwipeUp()==true");
+#endif
+
+ this.TranslateTo(
+ x: this.X
+ , y: finalTranslation
+ , length: 250
+ , easing: Easing.SpringIn);
+ }
else
- this.TranslateTo(this.X, finalTranslation, 250, Easing.SpringOut);
- ExpandedPercentage = GetClosestLockState(e.TotalY + this.TranslationY);
- isDragging = false;
+ {
+#if DEBUG
+ System.Console.WriteLine("[BottomDrawer] OnPanChanged() - DetectSwipeUp()==false");
+#endif
+
+ this.TranslateTo(
+ x: this.X
+ , y: finalTranslation
+ , length: 250
+ , easing: Easing.SpringOut);
+ }
+
+ // Note: [alex-d] this.TranslationY might change due to this.TranslateTo()
+ // -
+ double dragDistanceY2 = e.TotalY + this.TranslationY;
+
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] OnPanChanged() - call#2 GetClosestLockState({dragDistanceY2})");
+#endif
+ this.ExpandedPercentage = GetClosestLockStateAbsolute(dragDistanceY2);
+ this.isDragging = false;
+
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] OnPanChanged() - Completed | ExpandedPercentage=={ExpandedPercentage} | finalTranslation=={finalTranslation}");
+#endif
break;
+
case GestureStatus.Started:
- translationYStart = this.TranslationY;
- break;
+ this.translationYStart = this.TranslationY;
+
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] OnPanChanged() - Started | translationYStart=={translationYStart}");
+#endif
+ break;
+ }
+
+ if (LockStates.Length <= 0)
+ {
+ return;
+ }
+
+ int indexOfLastLockState = LockStates.Length - 1;
+ double lastLockState = LockStates[indexOfLastLockState];
+ double expandedPercentageBeforeLock = ExpandedPercentage;
+
+ if (ExpandedPercentage > lastLockState)
+ {
+ ExpandedPercentage = lastLockState;
}
- if (ExpandedPercentage > LockStates[LockStates.Length - 1])
- ExpandedPercentage = LockStates[LockStates.Length - 1];
- IsExpanded = ExpandedPercentage > 0;
+ IsExpanded = (ExpandedPercentage > 0);
+
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] OnPanChanged() - [END] | ExpandedPercentage=={ExpandedPercentage} | expandedPercentageBeforeLock=={expandedPercentageBeforeLock}");
+#endif
}
///
/// On tapped event
///
- private void OnTapped(object sender, EventArgs e)
+ private void OnTapped(
+ object sender
+ , EventArgs e
+ )
{
- if (!IsExpanded)
+#if DEBUG
+ System.Console.WriteLine("[BottomDrawer] OnTapped()");
+#endif
+ if (!this.IsExpanded)
{
- ExpandedPercentage = LockStates[1];
- IsExpanded = ExpandedPercentage > 0;
+ if (this.LockStates.Length >= 2)
+ {
+ // TODO: [alex-d] why hard-coded [1] index?
+ // -
+ this.ExpandedPercentage = LockStates[1];
+ }
+
+ this.IsExpanded = (this.ExpandedPercentage > 0);
}
}
@@ -232,11 +396,19 @@ private bool DetectSwipeUp(PanUpdatedEventArgs e)
///
/// Find the closest lock state when swip is finished
///
- private double GetClosestLockState(double TranslationY)
+ private double GetClosestLockStateAbsolute(double TranslationY)
{
// Play with these values to adjust the locking motions - this will change depending on the amount of content ona apge
double current = GetPropertionDistance(TranslationY);
+ double result = GetClosestLockStatePercentage(current);
+ return result;
+ }
+
+ private double GetClosestLockStatePercentage(double currentPercentageVisible)
+ {
+ double current = currentPercentageVisible;
+
// Calculate which lockstate it's the closest to
var smallestDistance = 10000.0;
var closestIndex = 0;
@@ -252,7 +424,11 @@ private double GetClosestLockState(double TranslationY)
}
}
- return LockStates[closestIndex];
+ double result = LockStates[closestIndex];
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] GetClosestLockState() | current=={current} | result=={result} | index=={closestIndex} | TranslationY=={TranslationY}");
+#endif
+ return result;
}
///
@@ -281,8 +457,25 @@ private double getProportionCoordinate(double proportion)
///
public void Dismiss()
{
- var finalTranslation = Math.Max(Math.Min(0, -1000), -Math.Abs(getProportionCoordinate(LockStates[0])));
- this.TranslateTo(this.X, finalTranslation, 450, Device.RuntimePlatform == Device.Android ? Easing.SpringOut : null);
+ double finalTranslation =
+ Math.Max(
+ Math.Min(0, -1000)
+ , -Math.Abs(getProportionCoordinate(LockStates[0]))
+ );
+
+ this.TranslateTo(
+ x: this.X
+ , y: finalTranslation
+ , length: 450
+ , easing:
+ Device.RuntimePlatform == Device.Android
+ ? Easing.SpringOut
+ : null
+ );
+
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] Dismiss() | finalTranslation=={finalTranslation}");
+#endif
}
///
@@ -290,8 +483,25 @@ public void Dismiss()
///
public void Open()
{
- var finalTranslation = Math.Max(Math.Min(0, -1000), -Math.Abs(getProportionCoordinate(LockStates[LockStates.Length - 1])));
- this.TranslateTo(this.X, finalTranslation, 150, Device.RuntimePlatform == Device.Android ? Easing.SpringIn : null);
+ double finalTranslation =
+ Math.Max(
+ Math.Min(0, -1000)
+ , -Math.Abs(getProportionCoordinate(LockStates[LockStates.Length - 1]))
+ );
+
+ this.TranslateTo(
+ x: this.X
+ , y: finalTranslation
+ , length: 150
+ , easing:
+ Device.RuntimePlatform == Device.Android
+ ? Easing.SpringIn
+ : null
+ );
+
+#if DEBUG
+ System.Console.WriteLine($"[BottomDrawer] Open() | finalTranslation=={finalTranslation}");
+#endif
}
#endregion Public