From 91e3ba62bf8d692bfb06b5a47b37ed57afc56496 Mon Sep 17 00:00:00 2001 From: Tsanie Lily Date: Sun, 17 May 2020 16:15:02 +0800 Subject: [PATCH] optimize: follow/illust page animation --- Pixiview.iOS/Renderers/AdaptedPageRenderer.cs | 11 +- Pixiview/App.cs | 1 + Pixiview/Illust/IllustCollectionPage.cs | 37 ++--- Pixiview/Illust/MainPage.xaml | 4 +- Pixiview/Illust/MainPage.xaml.cs | 17 +++ Pixiview/Illust/RankingPage.xaml.cs | 2 +- Pixiview/Illust/ViewIllustPage.xaml | 30 +++-- Pixiview/Illust/ViewIllustPage.xaml.cs | 49 ++++++- Pixiview/UI/AdaptedPage.cs | 127 ++++++++---------- 9 files changed, 154 insertions(+), 124 deletions(-) diff --git a/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs b/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs index 351c5a7..bc2202c 100644 --- a/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs +++ b/Pixiview.iOS/Renderers/AdaptedPageRenderer.cs @@ -23,7 +23,11 @@ namespace Pixiview.iOS.Renderers //var mode = ForPage.GetLargeTitleDisplay(page); //NavigationItem.LargeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Automatic; - page.InitOrientation((Orientation)UIDevice.CurrentDevice.Orientation); + //lastOrientation = UIDevice.CurrentDevice.Orientation; + //var landscape = + // lastOrientation == UIDeviceOrientation.LandscapeLeft || + // lastOrientation == UIDeviceOrientation.LandscapeRight; + //page.OnOrientationChanged(landscape); page.OnLoad(); } } @@ -86,7 +90,10 @@ namespace Pixiview.iOS.Renderers if (Element is AdaptedPage page) { AppShell.Current?.SetStatusBarHeight(UIApplication.SharedApplication.StatusBarFrame.Height); - page.OnOrientationChanged((Orientation)lastOrientation); + var landscape = + lastOrientation == UIDeviceOrientation.LandscapeLeft || + lastOrientation == UIDeviceOrientation.LandscapeRight; + page.OnOrientationChanged(landscape); } } } diff --git a/Pixiview/App.cs b/Pixiview/App.cs index 7ebea65..27d7d70 100644 --- a/Pixiview/App.cs +++ b/Pixiview/App.cs @@ -101,6 +101,7 @@ namespace Pixiview protected override void OnSleep() { + base.OnSleep(); } protected override void OnResume() diff --git a/Pixiview/Illust/IllustCollectionPage.cs b/Pixiview/Illust/IllustCollectionPage.cs index 81b2a8a..e1651c0 100644 --- a/Pixiview/Illust/IllustCollectionPage.cs +++ b/Pixiview/Illust/IllustCollectionPage.cs @@ -118,38 +118,34 @@ namespace Pixiview.Illust } } - protected override void OnSizeAllocated(double width, double height) - { - base.OnSizeAllocated(width, height); - int columns; #if __IOS__ - var oldMargin = PanelTopMargin; - Thickness newMargin; + public override void OnOrientationChanged(bool landscape) + { + base.OnOrientationChanged(landscape); if (StyleDefinition.IsFullscreenDevice) { - newMargin = width > height ? - AppShell.HalfNavigationBarOffset : - AppShell.NavigationBarOffset; - topOffset = width > height ? + topOffset = landscape ? AppShell.NavigationBarOffset.Top : AppShell.TotalBarOffset.Top; } else if (isPhone) { - newMargin = width > height ? - StyleDefinition.TopOffset16 : - StyleDefinition.TopOffset32; - topOffset = width > height ? + topOffset = landscape ? StyleDefinition.TopOffset32.Top : AppShell.TotalBarOffset.Top; } else { - // ipad - newMargin = StyleDefinition.TopOffset37; + // iPad topOffset = AppShell.TotalBarOffset.Top; } + } #endif + + protected override void OnSizeAllocated(double width, double height) + { + base.OnSizeAllocated(width, height); + int columns; if (width > height) { columns = isPhone ? 4 : 6; @@ -158,13 +154,6 @@ namespace Pixiview.Illust { columns = isPhone ? 2 : 4; } -#if __IOS__ - if (oldMargin != newMargin) - { - PanelTopMargin = newMargin; - OnPanelTopMarginChanged(oldMargin, newMargin); - } -#endif if (Columns != columns) { Columns = columns; @@ -301,7 +290,7 @@ namespace Pixiview.Illust if (scrollView.ScrollY > -topOffset) { #if __IOS__ - await scrollView.ScrollToAsync(0, -topOffset, true); + await scrollView.ScrollToAsync(scrollView.ScrollX, -topOffset, true); #else await scrollView.ScrollToAsync(0, -topOffset, false); #endif diff --git a/Pixiview/Illust/MainPage.xaml b/Pixiview/Illust/MainPage.xaml index 28e3486..4127ff4 100644 --- a/Pixiview/Illust/MainPage.xaml +++ b/Pixiview/Illust/MainPage.xaml @@ -32,12 +32,10 @@ + HeightRequest="{OnPlatform Android=40, iOS=50}"/> diff --git a/Pixiview/Illust/MainPage.xaml.cs b/Pixiview/Illust/MainPage.xaml.cs index bf1d31f..880150a 100644 --- a/Pixiview/Illust/MainPage.xaml.cs +++ b/Pixiview/Illust/MainPage.xaml.cs @@ -38,6 +38,23 @@ namespace Pixiview.Illust protected override ActivityIndicator LoadingIndicator => activityLoading; protected override double IndicatorMarginTop => 66; + protected override void OnSizeAllocated(double width, double height) + { + base.OnSizeAllocated(width, height); + searchBar.Margin = PageTopMargin; + panelBar.Margin = PanelTopMargin; + } + +#if __IOS__ + public override void OnOrientationChanged(bool landscape) + { + base.OnOrientationChanged(landscape); + + AnimateToMargin(searchBar, PageTopMargin); + AnimateToMargin(panelBar, PanelTopMargin); + } +#endif + protected override IEnumerable DoGetIllustList(IllustData data) { if (data.body == null) diff --git a/Pixiview/Illust/RankingPage.xaml.cs b/Pixiview/Illust/RankingPage.xaml.cs index 4268f96..7c6cd16 100644 --- a/Pixiview/Illust/RankingPage.xaml.cs +++ b/Pixiview/Illust/RankingPage.xaml.cs @@ -233,7 +233,7 @@ namespace Pixiview.Illust if (scrollDirection == ScrollDirection.Down) { // stop the scrolling - await scrollView.ScrollToAsync(0, scrollView.ScrollY, false); + await scrollView.ScrollToAsync(scrollView.ScrollX, scrollView.ScrollY, false); } await Task.WhenAll( labelCaret.RotateTo(180, easing: Easing.CubicOut), diff --git a/Pixiview/Illust/ViewIllustPage.xaml b/Pixiview/Illust/ViewIllustPage.xaml index f662955..a290b2a 100644 --- a/Pixiview/Illust/ViewIllustPage.xaml +++ b/Pixiview/Illust/ViewIllustPage.xaml @@ -15,7 +15,7 @@ - + @@ -29,20 +29,22 @@ - - - - - + + + + + + + - + + + @@ -241,7 +250,7 @@ namespace Pixiview.Illust var tapNext = new TapGestureRecognizer(); tapNext.Tapped += TapNext_Tapped; - return new Grid + var grid = new Grid { Children = { @@ -272,6 +281,10 @@ namespace Pixiview.Illust original } }; +#if __IOS__ + grid.SetBinding(Xamarin.Forms.Layout.PaddingProperty, nameof(IllustDetailItem.TopPadding)); +#endif + return grid; }); } @@ -288,10 +301,16 @@ namespace Pixiview.Illust PagePositionText = $"1/{items.Length}"; } +#if __IOS__ + var topMargin = PageTopMargin; +#endif for (var i = 0; i < items.Length; i++) { items[i] = new IllustDetailItem { +#if __IOS__ + TopPadding = topMargin, +#endif Id = illust.Id }; if (i == 0) @@ -320,12 +339,18 @@ namespace Pixiview.Illust App.DebugPrint($"local page count ({items.Length}) is not equals the remote one ({pages.body.Length})"); var tmp = new IllustDetailItem[pages.body.Length]; items.CopyTo(items, 0); +#if __IOS__ + var topMargin = PageTopMargin; +#endif for (var i = items.Length; i < tmp.Length; i++) { tmp[i] = new IllustDetailItem { Id = illustItem.Id, - Loading = true +#if __IOS__ + TopPadding = topMargin, +#endif + Loading = i == 0 }; } Illusts = items = tmp; @@ -703,6 +728,16 @@ namespace Pixiview.Illust nameof(Loading), typeof(bool), typeof(IllustDetailItem)); public static readonly BindableProperty DownloadingProperty = BindableProperty.Create( nameof(Downloading), typeof(bool), typeof(IllustDetailItem)); +#if __IOS__ + public static readonly BindableProperty TopPaddingProperty = BindableProperty.Create( + nameof(TopPadding), typeof(Thickness), typeof(IllustDetailItem)); + + public Thickness TopPadding + { + get => (Thickness)GetValue(TopPaddingProperty); + set => SetValue(TopPaddingProperty, value); + } +#endif public ImageSource Image { diff --git a/Pixiview/UI/AdaptedPage.cs b/Pixiview/UI/AdaptedPage.cs index 7a714f2..055b2bd 100644 --- a/Pixiview/UI/AdaptedPage.cs +++ b/Pixiview/UI/AdaptedPage.cs @@ -23,12 +23,9 @@ namespace Pixiview.UI get => (Thickness)GetValue(PanelTopMarginProperty); protected set => SetValue(PanelTopMarginProperty, value); } - public Orientation CurrentOrientation { get; private set; } public event EventHandler Load; public event EventHandler Unload; - public event EventHandler PageTopMarginChanged; - public event EventHandler OrientationChanged; protected static readonly bool isPhone = DeviceInfo.Idiom == DeviceIdiom.Phone; @@ -48,85 +45,83 @@ namespace Pixiview.UI Unload?.Invoke(this, EventArgs.Empty); } - public virtual void OnOrientationChanged(Orientation orientation) - { #if __IOS__ + public virtual void OnOrientationChanged(bool landscape) + { var oldMargin = PageTopMargin; + var oldPanelMargin = PanelTopMargin; Thickness newMargin; - switch (orientation) + Thickness newPanelMargin; + if (StyleDefinition.IsFullscreenDevice) { - case Orientation.Portrait: - newMargin = AppShell.TotalBarOffset; - break; - case Orientation.PortraitUpsideDown: - case Orientation.Unknown: - case Orientation.LandscapeLeft: - case Orientation.LandscapeRight: - default: - if (StyleDefinition.IsFullscreenDevice) - { - newMargin = AppShell.NavigationBarOffset; - } - else - { - newMargin = isPhone ? StyleDefinition.TopOffset32 : AppShell.TotalBarOffset; - } - break; + newMargin = landscape ? + AppShell.NavigationBarOffset : + AppShell.TotalBarOffset; + newPanelMargin = landscape ? + AppShell.HalfNavigationBarOffset : + AppShell.NavigationBarOffset; + } + else if (isPhone) + { + newMargin = landscape ? + StyleDefinition.TopOffset32 : + AppShell.TotalBarOffset; + newPanelMargin = landscape ? + StyleDefinition.TopOffset16 : + StyleDefinition.TopOffset32; + } + else + { + // iPad + newMargin = AppShell.TotalBarOffset; + newPanelMargin = StyleDefinition.TopOffset37; } if (oldMargin != newMargin) { PageTopMargin = newMargin; OnPageTopMarginChanged(oldMargin, newMargin); } -#endif - OrientationChanged?.Invoke(this, new OrientationEventArgs { CurrentOrientation = orientation }); + if (oldPanelMargin != newPanelMargin) + { + PanelTopMargin = newPanelMargin; + } } -#if __IOS__ + protected virtual void OnPageTopMarginChanged(Thickness old, Thickness @new) { } + protected override void OnSizeAllocated(double width, double height) { base.OnSizeAllocated(width, height); + OnOrientationChanged(width > height); + } - if (PageTopMargin == default) + protected void AnimateToMargin(View element, Thickness margin, bool animate = true) + { + var m = margin; + var start = element.Margin.Top - m.Top; + element.Margin = m; + if (start != 0 && animate) { - if (StyleDefinition.IsFullscreenDevice) + ViewExtensions.CancelAnimations(element); + element.Animate("margin", top => { - PageTopMargin = width > height ? - AppShell.NavigationBarOffset : - AppShell.TotalBarOffset; - } - else if (isPhone) + element.TranslationY = top; + }, + start, 0, +#if DEBUG + length: 500, +#else + length: 300, +#endif + easing: Easing.SinInOut, + finished: (v, r) => { - PageTopMargin = width > height ? - StyleDefinition.TopOffset32 : - AppShell.TotalBarOffset; - } - else - { - PageTopMargin = AppShell.TotalBarOffset; - } + element.TranslationY = 0; + }); } } #endif - public virtual void OnPageTopMarginChanged(Thickness old, Thickness @new) - { - PageTopMarginChanged?.Invoke(this, new ThicknessEventArgs - { - OldMargin = old, - NewMargin = @new - }); - } - - public virtual void OnPanelTopMarginChanged(Thickness old, Thickness @new) - { - } - - public void InitOrientation(Orientation orientation) - { - CurrentOrientation = orientation; - } - protected void Start(Action action) { if (Tap.IsBusy) @@ -175,18 +170,4 @@ namespace Pixiview.UI public Thickness OldMargin { get; set; } public Thickness NewMargin { get; set; } } - - public class OrientationEventArgs : EventArgs - { - public Orientation CurrentOrientation { get; set; } - } - - public enum Orientation - { - Unknown, - Portrait, - PortraitUpsideDown, - LandscapeLeft, - LandscapeRight - } }