feature: scroll animation in follow/ranking page

This commit is contained in:
Tsanie Lily 2020-05-14 11:21:43 +08:00
parent ef70d7108a
commit 6235430ded
4 changed files with 74 additions and 66 deletions

View File

@ -12,7 +12,8 @@
IconImageSource="{DynamicResource FontIconRefresh}"/>
</ContentPage.ToolbarItems>
<Grid>
<ScrollView HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never">
<ScrollView HorizontalOptions="Fill" HorizontalScrollBarVisibility="Never"
Scrolled="ScrollView_Scrolled">
<u:FlowLayout ItemsSource="{Binding Illusts}"
HorizontalOptions="Fill" Column="{Binding Columns}"
RowSpacing="16" ColumnSpacing="16"
@ -24,7 +25,8 @@
</u:FlowLayout.Margin>
</u:FlowLayout>
</ScrollView>
<u:BlurryPanel VerticalOptions="Start" HeightRequest="{OnPlatform Android=40, iOS=50}"
<u:BlurryPanel x:Name="panelBar" VerticalOptions="Start"
HeightRequest="{OnPlatform Android=40, iOS=50}"
Margin="{Binding PanelTopMargin}"/>
<SearchBar x:Name="searchBar" Placeholder="{r:Text Search}"
HeightRequest="{OnPlatform Android=40, iOS=50}"

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Pixiview.Utils;
using Xamarin.Forms;
@ -19,6 +18,9 @@ namespace Pixiview.Illust
set => SetValue(KeywordsProperty, value);
}
private double lastScrollY = double.MinValue;
private ScrollDirection scrollDirection = ScrollDirection.Stop;
public MainPage()
{
Resources.Add("cardView", GetCardViewTemplate());
@ -26,24 +28,17 @@ namespace Pixiview.Illust
#if __IOS__
searchBar.BackgroundColor = Color.Transparent;
#elif __ANDROID__
#else
searchBar.SetDynamicResource(SearchBar.TextColorProperty, UI.Theme.ThemeBase.TextColor);
searchBar.SetDynamicResource(SearchBar.PlaceholderColorProperty, UI.Theme.ThemeBase.SubTextColor);
searchBar.SetDynamicResource(BackgroundColorProperty, UI.Theme.ThemeBase.WindowColor);
#endif
}
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data, ICommand command)
protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data)
{
return data.body.page.follow.Select(i =>
{
var item = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == i.ToString())?.ConvertToItem();
if (item != null)
{
item.IllustTapped = command;
}
return item;
});
data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == i.ToString())?.ConvertToItem());
}
protected override IllustData DoLoadIllustData(bool force)
@ -73,5 +68,41 @@ namespace Pixiview.Illust
Task.Run(() => App.OpenUrl(new Uri("pixiview://example.com/artworks/" + key)));
}
}
#if __IOS__
private const int searchBarHeight = 50;
#else
private const int searchBarHeight = 40;
#endif
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
var y = e.ScrollY;
if (y > lastScrollY)
{
// down
if (scrollDirection != ScrollDirection.Down && y > searchBarHeight - topOffset)
{
scrollDirection = ScrollDirection.Down;
ViewExtensions.CancelAnimations(searchBar);
ViewExtensions.CancelAnimations(panelBar);
searchBar.TranslateTo(0, -searchBarHeight, easing: Easing.CubicIn);
panelBar.TranslateTo(0, -searchBarHeight, easing: Easing.CubicIn);
}
}
else
{
// up
if (scrollDirection != ScrollDirection.Up)
{
scrollDirection = ScrollDirection.Up;
ViewExtensions.CancelAnimations(searchBar);
ViewExtensions.CancelAnimations(panelBar);
searchBar.TranslateTo(0, 0, easing: Easing.CubicOut);
panelBar.TranslateTo(0, 0, easing: Easing.CubicOut);
}
}
lastScrollY = y;
}
}
}

View File

@ -5,7 +5,8 @@
xmlns:u="clr-namespace:Pixiview.UI"
xmlns:r="clr-namespace:Pixiview.Resources"
x:Class="Pixiview.Illust.RankingPage"
BackgroundColor="{DynamicResource WindowColor}">
BackgroundColor="{DynamicResource WindowColor}"
Title="{r:Text Ranking}">
<Shell.TitleView>
<Grid VerticalOptions="Fill" ColumnSpacing="6"
HorizontalOptions="{x:OnPlatform Android=Start, iOS=Fill}">
@ -23,7 +24,8 @@
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</Label.GestureRecognizers>
</Label>
<Label Grid.Column="2" Text="{Binding PanelState}"
<Label Grid.Column="2" x:Name="labelCaret"
Text="{DynamicResource IconCaretDown}"
TextColor="{DynamicResource TextColor}"
FontFamily="{DynamicResource IconSolidFontFamily}"
FontSize="Small"
@ -44,6 +46,7 @@
</ScrollView>
<u:BlurryPanel x:Name="panelFilter" VerticalOptions="Start" Opacity="0"
Margin="{Binding PanelTopMargin}"
BackgroundColor="{DynamicResource WindowColor}"
HeightRequest="{Binding Height, Source={x:Reference gridFilter}}"/>
<Grid x:Name="gridFilter" VerticalOptions="Start" Opacity="0"
Margin="{Binding PageTopMargin}" Padding="10">

View File

@ -2,9 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Pixiview.Resources;
using Pixiview.UI;
using Pixiview.Utils;
using Xamarin.Essentials;
using Xamarin.Forms;
@ -16,8 +14,6 @@ namespace Pixiview.Illust
private static readonly string[] segmentDates = { "daily", "weekly", "monthly", "male" };
private static readonly object sync = new object();
public static readonly BindableProperty PanelStateProperty = BindableProperty.Create(
nameof(PanelState), typeof(string), typeof(RankingPage), StyleDefinition.IconCaretDown);
public static readonly BindableProperty SegmentDateProperty = BindableProperty.Create(
nameof(SegmentDate), typeof(int), typeof(RankingPage), propertyChanged: OnSegmentDatePropertyChanged);
public static readonly BindableProperty SegmentTypeProperty = BindableProperty.Create(
@ -54,11 +50,6 @@ namespace Pixiview.Illust
}
}
public string PanelState
{
get => (string)GetValue(PanelStateProperty);
set => SetValue(PanelStateProperty, value);
}
public int SegmentDate
{
get => (int)GetValue(SegmentDateProperty);
@ -70,8 +61,9 @@ namespace Pixiview.Illust
set => SetValue(SegmentTypeProperty, value);
}
private double lastScrollY = double.MinValue;
private bool isFilterVisible;
private double topOffset;
private string lastQueryKey;
private string queryDate;
private int currentPage;
@ -91,30 +83,6 @@ namespace Pixiview.Illust
currentPage = 1;
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
if (StyleDefinition.IsFullscreenDevice)
{
topOffset = width > height ?
AppShell.NavigationBarOffset.Top :
AppShell.TotalBarOffset.Top;
}
else if (isPhone)
{
topOffset = width > height ?
StyleDefinition.TopOffset32.Top :
AppShell.TotalBarOffset.Top;
}
else
{
// TODO: ipad
topOffset = AppShell.TotalBarOffset.Top;
}
}
protected override bool IsLazyload => true;
protected override void DoIllustsLoaded(IllustCollection collection)
{
var now = IllustCollection;
@ -131,17 +99,9 @@ namespace Pixiview.Illust
}
}
protected override IEnumerable<IllustItem> DoGetIllustList(IllustRankingData data, ICommand command)
protected override IEnumerable<IllustItem> DoGetIllustList(IllustRankingData data)
{
return data.contents.Select(i =>
{
var item = i.ConvertToItem();
if (item != null)
{
item.IllustTapped = command;
}
return item;
});
return data.contents.Select(i => i.ConvertToItem());
}
protected override IllustRankingData DoLoadIllustData(bool force)
@ -176,8 +136,8 @@ namespace Pixiview.Illust
if (flag)
{
isFilterVisible = true;
PanelState = StyleDefinition.IconCaretUp;
await Task.WhenAll(
labelCaret.RotateTo(180, easing: Easing.CubicOut),
gridFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
gridFilter.FadeTo(1, easing: Easing.CubicOut),
panelFilter.TranslateTo(0, 0, easing: Easing.CubicOut),
@ -187,12 +147,12 @@ namespace Pixiview.Illust
else
{
isFilterVisible = false;
PanelState = StyleDefinition.IconCaretDown;
await Task.WhenAll(
gridFilter.TranslateTo(0, -100, easing: Easing.CubicOut),
gridFilter.FadeTo(0, easing: Easing.CubicOut),
panelFilter.TranslateTo(0, -100, easing: Easing.CubicOut),
panelFilter.FadeTo(0, easing: Easing.CubicOut)
labelCaret.RotateTo(0, easing: Easing.CubicIn),
gridFilter.TranslateTo(0, -100, easing: Easing.CubicIn),
gridFilter.FadeTo(0, easing: Easing.CubicIn),
panelFilter.TranslateTo(0, -100, easing: Easing.CubicIn),
panelFilter.FadeTo(0, easing: Easing.CubicIn)
);
}
}
@ -215,8 +175,19 @@ namespace Pixiview.Illust
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
var y = e.ScrollY;
if (y > lastScrollY)
{
// down
if (isFilterVisible)
{
ToggleFilterPanel(false);
}
}
lastScrollY = y;
var bottomOffset = scrollView.ContentSize.Height - (scrollView.LayoutAreaOverride.Height * 2);
if (e.ScrollY > 0 && e.ScrollY + topOffset > bottomOffset)
if (y > 0 && y + topOffset > bottomOffset)
{
bool refresh = false;
lock (sync)
@ -235,6 +206,7 @@ namespace Pixiview.Illust
}
if (refresh)
{
App.DebugPrint($"start to load page {nextPage}");
StartLoad(true);
}
}