feature: scroll animation in follow/ranking page
This commit is contained in:
parent
ef70d7108a
commit
6235430ded
@ -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}"
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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">
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user