Skip to content

Commit

Permalink
feat(mobile): use animation for LVB.ScrollIntoView
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaoy312 committed Aug 31, 2022
1 parent 34b19ca commit a352416
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 13 deletions.
7 changes: 7 additions & 0 deletions doc/articles/feature-flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ By default, this mode is enabled for the time being, as it is quite disrupting.
Use `Uno.UI.FeatureConfiguration.UIElement.UseLegacyClipping` to control this mode.
Additionally, `Uno.UI.FeatureConfiguration.UIElement.ShowClippingBounds` can be used to show the clipping boundaries to determine if the behavior of the clipping is appropriate.

## ListView Scrolling

On iOS and Android platforms specifically, `ListView.ScrollIntoView` performs an animated scrolling instead of an instant scrolling than other platforms.

This feature can be toggled with: `Uno.UI.FeatureConfiguration.ListViewBase.AnimateScrollIntoView`.
Alternatively, `Uno.UI.Helpers.ListViewHelper` offer two extension methods, `InstantScrollToIndex` and `SmoothScrollToIndex`, to perform a specific type of scrolling irrespective of the flag set.

# UWP Styles default

By default, Uno favors the default UWP XAML styles over the native styles for Button, Slider, ComboBox, etc...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2476,7 +2476,7 @@ public async Task When_Smooth_Scrolling()
Assert.IsTrue(count < source.Length, $"Native ListView is not {(count.HasValue ? $"virtualized (count={count})" : "loaded")}.");

// scroll to bottom
Uno.UI.Helpers.ListViewHelper.SmoothScroll(lv, lv.Items.Count - 1);
Uno.UI.Helpers.ListViewHelper.SmoothScrollToIndex(lv, lv.Items.Count - 1);
await Task.Delay(2000);
await WindowHelper.WaitForIdle();

Expand Down
12 changes: 12 additions & 0 deletions src/Uno.UI/FeatureConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,18 @@ public static class ListViewBase
/// the default value at the UWP default of 4.0.
/// </summary>
public static double? DefaultCacheLength = 1.0;

#if __IOS__ || __ANDROID__
/// <summary>
/// Sets a flag indicating whether <see cref="Windows.UI.Xaml.Controls.ListViewBase.ScrollIntoView(object)"/> will be animated smoothly or instant.
/// </summary>
/// <remarks>
/// Regardless of the value set, <see cref="Uno.UI.Helpers.ListViewHelper.InstantScrollToIndex(Windows.UI.Xaml.Controls.ListViewBase, int)"/>
/// and <see cref="Uno.UI.Helpers.ListViewHelper.SmoothScrollToIndex(Windows.UI.Xaml.Controls.ListViewBase, int)"/>
/// can be used to force a specific behavior.
/// </remarks>
public static bool AnimateScrollIntoView { get; set; } = true;
#endif
}

#if __ANDROID__
Expand Down
20 changes: 16 additions & 4 deletions src/Uno.UI/Helpers/ListViewHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,28 @@ public static partial class ListViewHelper
public static NativeListViewBase GetNativePanel(ListViewBase lvb) => lvb.NativePanel;

#if __IOS__
public static void SmoothScroll(this ListViewBase lvb, int index, UIKit.UICollectionViewScrollPosition scrollPosition = UIKit.UICollectionViewScrollPosition.Top)
public static void InstantScrollToIndex(this ListViewBase lvb, int index, UIKit.UICollectionViewScrollPosition scrollPosition = UIKit.UICollectionViewScrollPosition.Top)
{
var indexPath = lvb.GetIndexPathFromIndex(index)?.ToNSIndexPath() ?? throw new IndexOutOfRangeException();

lvb.NativePanel.ScrollToItem(indexPath, scrollPosition, animated: true);
lvb.NativePanel?.ScrollToItem(indexPath, scrollPosition, animated: false);
}

public static void SmoothScrollToIndex(this ListViewBase lvb, int index, UIKit.UICollectionViewScrollPosition scrollPosition = UIKit.UICollectionViewScrollPosition.Top)
{
var indexPath = lvb.GetIndexPathFromIndex(index)?.ToNSIndexPath() ?? throw new IndexOutOfRangeException();

lvb.NativePanel?.ScrollToItem(indexPath, scrollPosition, animated: true);
}
#elif __ANDROID__
public static void SmoothScroll(this ListViewBase lvb, int index)
public static void InstantScrollToIndex(this ListViewBase lvb, int index)
{
lvb.NativePanel?.ScrollToPosition(index);
}

public static void SmoothScrollToIndex(this ListViewBase lvb, int index)
{
lvb.NativePanel.SmoothScrollToPosition(index);
lvb.NativePanel?.SmoothScrollToPosition(index);
}
#endif
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public abstract partial class ListViewBase : BindableUICollectionView, IFramewor
/// <summary>
/// This property enables animations when using the ScrollIntoView Method.
/// </summary>
public bool AnimateScrollIntoView { get; set; } = false;
public bool AnimateScrollIntoView { get; set; } = Uno.UI.FeatureConfiguration.ListViewBase.AnimateScrollIntoView;
#endregion

#region Members
Expand Down
16 changes: 11 additions & 5 deletions src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBase.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,13 +322,19 @@ public void ScrollIntoView(object item, ScrollIntoViewAlignment alignment)
// occurring during scrolling are not always properly picked up by the layouting/rendering engine.
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var index = IndexFromItem(item);
if (index < 0)
if (IndexFromItem(item) is var index and >= 0)
{
return;
if (Uno.UI.FeatureConfiguration.ListViewBase.AnimateScrollIntoView)
{
NativePanel?.SmoothScrollToPosition(index);
}
else
{
var displayPosition = ConvertIndexToDisplayPosition(index);

NativePanel?.ScrollIntoView(displayPosition, alignment);
}
}
var displayPosition = ConvertIndexToDisplayPosition(index);
NativePanel?.ScrollIntoView(displayPosition, alignment);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public partial class ListViewBase
[Uno.UnoOnly]
public bool UseCollectionAnimations { get; set; } = true;

private bool _animateScrollIntoView;
private bool _animateScrollIntoView = Uno.UI.FeatureConfiguration.ListViewBase.AnimateScrollIntoView;
public bool AnimateScrollIntoView
{
get { return _animateScrollIntoView; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public partial class NativeListViewBase : UICollectionView
/// <summary>
/// This property enables animations when using the ScrollIntoView Method.
/// </summary>
public bool AnimateScrollIntoView { get; set; } = false;
public bool AnimateScrollIntoView { get; set; } = Uno.UI.FeatureConfiguration.ListViewBase.AnimateScrollIntoView;
#endregion

#region Members
Expand Down

0 comments on commit a352416

Please sign in to comment.