detail page

This commit is contained in:
Tsanie Lily 2020-05-06 00:16:24 +08:00
parent 98833961a0
commit 190615ab03
15 changed files with 295 additions and 45 deletions

View File

@ -75,7 +75,7 @@
<Compile Include="Renderers\CardViewRenderer.cs" />
<Compile Include="Renderers\RoundImageRenderer.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Renderers\NavigationPageRenderer.cs" />
<Compile Include="Renderers\AdaptedNavigationPageRenderer.cs" />
</ItemGroup>
<ItemGroup>
<InterfaceDefinition Include="Resources\LaunchScreen.storyboard" />

View File

@ -0,0 +1,26 @@
using Pixiview.iOS.Renderers;
using Pixiview.UI;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(AdaptedNavigationPage), typeof(AdaptedNavigationPageRenderer))]
namespace Pixiview.iOS.Renderers
{
public class AdaptedNavigationPageRenderer : NavigationRenderer
{
public override void WillMoveToParentViewController(UIViewController parent)
{
if (Element is AdaptedNavigationPage navigation)
{
NavigationBar.Translucent = true;
var barHeight = NavigationBar.Frame.Height;
var statusHeight = UIApplication.SharedApplication.StatusBarFrame.Height;
navigation.SetNavigationBarHeight(barHeight, statusHeight);
}
base.WillMoveToParentViewController(parent);
}
}
}

View File

@ -24,10 +24,21 @@ namespace Pixiview.iOS.Renderers
//var mode = ForPage.GetLargeTitleDisplay(page);
//NavigationItem.LargeTitleDisplayMode = UINavigationItemLargeTitleDisplayMode.Automatic;
page.InitOrientation((Orientation)UIDevice.CurrentDevice.Orientation);
page.OnLoad();
}
}
protected override void Dispose(bool disposing)
{
if (Element is AdaptedPage page)
{
page.OnUnload();
}
base.Dispose(disposing);
}
public override bool PrefersHomeIndicatorAutoHidden => Screen.GetHomeIndicatorAutoHidden(Element);
public override void ViewDidAppear(bool animated)

View File

@ -1,18 +0,0 @@
using Pixiview.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(NavigationPage), typeof(NavigationPageRenderer))]
namespace Pixiview.iOS.Renderers
{
public class NavigationPageRenderer : NavigationRenderer
{
public override void WillMoveToParentViewController(UIViewController parent)
{
NavigationBar.Translucent = true;
base.WillMoveToParentViewController(parent);
}
}
}

View File

@ -13,12 +13,6 @@
BackgroundColor="{DynamicResource WindowColor}"
Title="{r:Text Follow}"
OrientationChanged="Page_OrientationChanged">
<!--<NavigationPage.TitleView>
<u:NavigationTitle Title="{r:Text Follow}"
IsRightButtonVisible="True"
RightButtonText="{DynamicResource IconOption}"
RightButtonClicked="NavigationTitle_RightButtonClicked"/>
</NavigationPage.TitleView>-->
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" Clicked="NavigationTitle_RightButtonClicked"
IconImageSource="{DynamicResource FontIconOption}"/>
@ -84,7 +78,7 @@
</u:FlowLayout>
</ScrollView>
<ActivityIndicator IsRunning="True" IsEnabled="True" IsVisible="{Binding Loading}"
Margin="20"
Margin="120" Color="{DynamicResource TextColor}"
HorizontalOptions="Center" VerticalOptions="Start"/>
</Grid>
</u:AdaptedPage>

View File

@ -29,7 +29,6 @@ namespace Pixiview
private static void OnLoadingPropertyChanged(BindableObject obj, object oldValue, object newValue)
{
var page = (MainPage)obj;
var before = (bool)oldValue;
var now = (bool)newValue;
if (!page.loaded && now && Stores.NetworkAvailable)
{
@ -64,9 +63,9 @@ namespace Pixiview
public MainPage()
{
BindingContext = this;
InitializeComponent();
BindingContext = this;
commandIllustImageTapped = new Command<IllustItem>(OnIllustImageTapped);
}
@ -75,6 +74,10 @@ namespace Pixiview
public override void OnLoad()
{
App.DebugPrint($"folder: {Stores.PersonalFolder}");
if (!loaded)
{
Loading = true;
}
}
protected override void OnAppearing()
@ -82,10 +85,6 @@ namespace Pixiview
base.OnAppearing();
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
if (!loaded)
{
Loading = true;
}
}
protected override void OnDisappearing()
@ -197,8 +196,17 @@ namespace Pixiview
case Orientation.Portrait:
Columns = 2;
break;
case Orientation.Unknown:
case Orientation.PortraitUpsideDown:
if (DeviceInfo.Idiom == DeviceIdiom.Phone)
{
Columns = 4;
}
else
{
Columns = 2;
}
break;
case Orientation.Unknown:
case Orientation.LandscapeLeft:
case Orientation.LandscapeRight:
default:

View File

@ -0,0 +1,16 @@
using Xamarin.Forms;
namespace Pixiview.UI
{
public class AdaptedNavigationPage : NavigationPage
{
public AdaptedNavigationPage(Page page) : base(page)
{
}
public void SetNavigationBarHeight(double barHeight, double statusHeight)
{
StyleDefinition.SetNavigationBarHeight(barHeight, statusHeight);
}
}
}

View File

@ -17,7 +17,10 @@ namespace Pixiview.UI
set => SetValue(StatusBarPaddingProperty, value);
}
public Orientation CurrentOrientation { get; private set; }
public event EventHandler Load;
public event EventHandler Unload;
public event EventHandler<OrientationEventArgs> OrientationChanged;
public virtual void OnLoad()
@ -25,6 +28,11 @@ namespace Pixiview.UI
Load?.Invoke(this, EventArgs.Empty);
}
public virtual void OnUnload()
{
Unload?.Invoke(this, EventArgs.Empty);
}
public virtual void OnOrientationChanged(Orientation orientation)
{
if (orientation == Orientation.LandscapeLeft || orientation == Orientation.PortraitUpsideDown)
@ -43,6 +51,11 @@ namespace Pixiview.UI
OrientationChanged?.Invoke(this, new OrientationEventArgs { CurrentOrientation = orientation });
}
public void InitOrientation(Orientation orientation)
{
CurrentOrientation = orientation;
}
protected void Start(Action action)
{
if (Tap.IsBusy)

View File

@ -9,13 +9,41 @@ namespace Pixiview.UI
public const double FontSizeTitle = 18.0;
public const double FontSizeTitleIcon = 24.0;
public static readonly Thickness ScreenBottomPadding;
public static readonly Thickness HorizonLeft10 = new Thickness(10, 0, 0, 0);
public static readonly Thickness HorizonRight10 = new Thickness(0, 0, 10, 0);
public static readonly Thickness LeftBottom10 = new Thickness(10, 0, 0, 10);
public static readonly GridLength TitleIconWidth = 40;
public static Thickness NavigationBarOffset;
public static Thickness StatusBarOffset;
public static Thickness TotalBarOffset;
public const string IconLayer = "\uf302";
public const string IconOption = "\uf013";
public const string IconDownload = "\uf019";
static StyleDefinition()
{
if (IsFullscreenDevice)
{
if (DeviceInfo.Idiom == DeviceIdiom.Phone)
{
ScreenBottomPadding = new Thickness(0, 0, 0, 26);
}
else
{
ScreenBottomPadding = new Thickness(0, 0, 0, 16);
}
}
}
public static void SetNavigationBarHeight(double barHeight, double statusHeight)
{
NavigationBarOffset = new Thickness(0, barHeight, 0, 0);
StatusBarOffset = new Thickness(0, statusHeight, 0, 0);
TotalBarOffset = new Thickness(0, barHeight + statusHeight, 0, 0);
}
private static bool? _isFullscreenDevice;
public static bool IsFullscreenDevice

View File

@ -34,6 +34,7 @@ namespace Pixiview.UI.Theme
Add(MainColor, Color.FromRgb(0x33, 0x33, 0x33));
Add(MainTextColor, Color.White);
Add(SubColor, Color.FromRgb(0x33, 0x33, 0x33));
Add(MaskColor, Color.FromRgba(0xff, 0xff, 0xff, 0x50));
}
}
}

View File

@ -34,6 +34,7 @@ namespace Pixiview.UI.Theme
Add(MainColor, Color.FromRgb(0xf0, 0xf0, 0xf0)); // Color.FromRgb(0x7f, 0x99, 0xc6)
Add(MainTextColor, Color.Black);
Add(SubColor, Color.FromRgb(0xf0, 0xf0, 0xf0)); // Color.FromRgb(0xfa, 0xfa, 0xf0)
Add(MaskColor, Color.FromRgba(0, 0, 0, 0x50));
}
}
}

View File

@ -7,6 +7,7 @@ namespace Pixiview.UI.Theme
public const string TitleButton = nameof(TitleButton);
public const string TitleLabel = nameof(TitleLabel);
public const string FontIconOption = nameof(FontIconOption);
public const string FontIconDownload = nameof(FontIconDownload);
public const string StatusBarStyle = nameof(StatusBarStyle);
public const string WindowColor = nameof(WindowColor);
@ -15,6 +16,7 @@ namespace Pixiview.UI.Theme
public const string MainColor = nameof(MainColor);
public const string MainTextColor = nameof(MainTextColor);
public const string SubColor = nameof(SubColor);
public const string MaskColor = nameof(MaskColor);
public const string IconLightFontFamily = nameof(IconLightFontFamily);
public const string IconRegularFontFamily = nameof(IconRegularFontFamily);
@ -23,14 +25,19 @@ namespace Pixiview.UI.Theme
public const string FontSizeTitle = nameof(FontSizeTitle);
public const string FontSizeTitleIcon = nameof(FontSizeTitleIcon);
//public const string Horizon10 = nameof(Horizon10);
public const string ScreenBottomPadding = nameof(ScreenBottomPadding);
public const string NavigationBarHeight = nameof(NavigationBarHeight);
public const string IconOption = nameof(IconOption);
public const string IconDownload = nameof(IconDownload);
protected void InitResources()
{
Add(FontSizeTitle, StyleDefinition.FontSizeTitle);
Add(FontSizeTitleIcon, StyleDefinition.FontSizeTitleIcon);
//Add(Horizon10, StyleDefinition.Horizon10);
Add(ScreenBottomPadding, StyleDefinition.ScreenBottomPadding);
Add(IconOption, StyleDefinition.IconOption);
Add(IconDownload, StyleDefinition.IconDownload);
if (App.ExtraResources != null)
{
@ -40,6 +47,9 @@ namespace Pixiview.UI.Theme
}
}
var mainColor = this[MainTextColor];
var iconSolidFontFamily = (string)this[IconSolidFontFamily];
Add(TitleLabel, new Style(typeof(Label))
{
Setters =
@ -48,27 +58,34 @@ namespace Pixiview.UI.Theme
new Setter { Property = View.HorizontalOptionsProperty, Value = LayoutOptions.Fill },
new Setter { Property = Label.HorizontalTextAlignmentProperty, Value = TextAlignment.Center },
new Setter { Property = Label.FontSizeProperty, Value = StyleDefinition.FontSizeTitle },
new Setter { Property = Label.TextColorProperty, Value = this[MainTextColor] }
new Setter { Property = Label.TextColorProperty, Value = mainColor }
}
});
Add(TitleButton, new Style(typeof(Button))
{
Setters =
{
new Setter { Property = Button.BorderWidthProperty, Value = 0.0 },
new Setter { Property = VisualElement.BackgroundColorProperty, Value = Color.Transparent },
new Setter { Property = Button.FontFamilyProperty, Value = this[IconSolidFontFamily] },
new Setter { Property = Button.FontFamilyProperty, Value = iconSolidFontFamily },
new Setter { Property = Button.FontSizeProperty, Value = StyleDefinition.FontSizeTitleIcon },
new Setter { Property = Button.TextColorProperty, Value = this[MainTextColor] }
new Setter { Property = Button.TextColorProperty, Value = mainColor }
}
});
Add(FontIconOption, new FontImageSource
{
FontFamily = (string)this[IconSolidFontFamily],
FontFamily = iconSolidFontFamily,
Glyph = StyleDefinition.IconOption,
Size = StyleDefinition.FontSizeTitle
});
Add(FontIconDownload, new FontImageSource
{
FontFamily = iconSolidFontFamily,
Glyph = StyleDefinition.IconDownload,
Size = StyleDefinition.FontSizeTitle
});
}
}
}

View File

@ -1,13 +1,14 @@
using Pixiview.UI.Theme;
using Pixiview.UI;
using Pixiview.UI.Theme;
using Xamarin.Forms;
namespace Pixiview.Utils
{
public static class UIFactory
{
public static NavigationPage CreateNavigationPage(Page root)
public static AdaptedNavigationPage CreateNavigationPage(Page root)
{
var navigation = new NavigationPage(root);
var navigation = new AdaptedNavigationPage(root);
//navigation.SetDynamicResource(NavigationPage.BarBackgroundColorProperty, ThemeBase.MainColor);
navigation.SetDynamicResource(NavigationPage.BarTextColorProperty, ThemeBase.MainTextColor);
navigation.SetDynamicResource(VisualElement.BackgroundColorProperty, ThemeBase.WindowColor);

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<u:AdaptedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:p="clr-namespace:Pixiview"
xmlns:u="clr-namespace:Pixiview.UI"
xmlns:util="clr-namespace:Pixiview.Utils"
xmlns:r="clr-namespace:Pixiview.Resources"
@ -8,5 +9,33 @@
util:Screen.StatusBarStyle="{DynamicResource StatusBarStyle}"
util:Screen.HomeIndicatorAutoHidden="True"
BackgroundColor="{DynamicResource WindowColor}"
Title="{r:Text Preview}">
Title="{r:Text Preview}"
OrientationChanged="Page_OrientationChanged">
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" Clicked="Download_Clicked"
IconImageSource="{DynamicResource FontIconDownload}"/>
</ContentPage.ToolbarItems>
<Grid Margin="{Binding PageTopMargin}">
<CarouselView ItemsSource="{Binding Illusts}" HorizontalScrollBarVisibility="Never"
PositionChanged="CarouselView_PositionChanged">
<CarouselView.ItemTemplate>
<DataTemplate x:DataType="p:IllustDetailItem">
<Grid>
<Image Source="{Binding Image}"
HorizontalOptions="Fill" VerticalOptions="Fill"
Aspect="AspectFit"/>
<ActivityIndicator IsRunning="True" IsEnabled="True" IsVisible="{Binding Loading}"
Color="{DynamicResource TextColor}"/>
</Grid>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<u:RoundLabel Text="{Binding PagePositionText}"
BackgroundColor="{DynamicResource MaskColor}" Margin="0, 6, 6, 0"
Padding="6, 4" CornerRadius="6"
HorizontalOptions="End" VerticalOptions="Start"
FontSize="Micro" TextColor="White"
IsVisible="{Binding IsPageVisible}"/>
</Grid>
</u:AdaptedPage>

View File

@ -1,18 +1,141 @@
using System;
using System.Collections.Generic;
using System;
using Pixiview.UI;
using Pixiview.UI.Theme;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Pixiview
{
public partial class ViewIllustPage : AdaptedPage
{
private readonly IllustItem illust;
public static readonly BindableProperty IllustsProperty = BindableProperty.Create(
nameof(Illusts), typeof(IllustDetailItem[]), typeof(ViewIllustPage));
public static readonly BindableProperty PagePositionTextProperty = BindableProperty.Create(
nameof(PagePositionText), typeof(string), typeof(ViewIllustPage));
public static readonly BindableProperty IsPageVisibleProperty = BindableProperty.Create(
nameof(IsPageVisible), typeof(bool), typeof(ViewIllustPage));
public static readonly BindableProperty PageTopMarginProperty = BindableProperty.Create(
nameof(PageTopMargin), typeof(Thickness), typeof(ViewIllustPage));
public static readonly BindableProperty IllustItemProperty = BindableProperty.Create(
nameof(IllustItem), typeof(IllustItem), typeof(ViewIllustPage));
public IllustDetailItem[] Illusts
{
get => (IllustDetailItem[])GetValue(IllustsProperty);
set => SetValue(IllustsProperty, value);
}
public string PagePositionText
{
get => (string)GetValue(PagePositionTextProperty);
set => SetValue(PagePositionTextProperty, value);
}
public bool IsPageVisible
{
get => (bool)GetValue(IsPageVisibleProperty);
set => SetValue(IsPageVisibleProperty, value);
}
public Thickness PageTopMargin
{
get => (Thickness)GetValue(PageTopMarginProperty);
set => SetValue(PageTopMarginProperty, value);
}
public IllustItem IllustItem
{
get => (IllustItem)GetValue(IllustItemProperty);
private set => SetValue(IllustItemProperty, value);
}
public ViewIllustPage(IllustItem illust)
{
this.illust = illust;
IllustItem = illust;
BindingContext = this;
InitializeComponent();
}
public override void OnLoad()
{
var illust = IllustItem;
if (illust == null)
{
return;
}
var items = new IllustDetailItem[illust.PageCount];
if (items.Length > 0)
{
IsPageVisible = true;
PagePositionText = $"1/{items.Length}";
}
items[0] = new IllustDetailItem
{
Image = illust.Image,
Loading = true
};
Illusts = items;
UpdatePageTopMargin(CurrentOrientation);
}
private void CarouselView_PositionChanged(object sender, PositionChangedEventArgs e)
{
PagePositionText = $"{e.CurrentPosition + 1}/{Illusts.Length}";
}
private void Page_OrientationChanged(object sender, OrientationEventArgs e)
{
UpdatePageTopMargin(e.CurrentOrientation);
}
private void UpdatePageTopMargin(Orientation orientation)
{
switch (orientation)
{
case Orientation.Portrait:
PageTopMargin = StyleDefinition.TotalBarOffset;
break;
case Orientation.PortraitUpsideDown:
if (DeviceInfo.Idiom == DeviceIdiom.Phone)
{
PageTopMargin = StyleDefinition.NavigationBarOffset;
}
else
{
PageTopMargin = StyleDefinition.TotalBarOffset;
}
break;
case Orientation.Unknown:
case Orientation.LandscapeLeft:
case Orientation.LandscapeRight:
default:
PageTopMargin = StyleDefinition.NavigationBarOffset;
break;
}
}
private void Download_Clicked(object sender, EventArgs e)
{
}
}
public class IllustDetailItem : BindableObject
{
public static readonly BindableProperty ImageProperty = BindableProperty.Create(
nameof(Image), typeof(ImageSource), typeof(IllustDetailItem));
public static readonly BindableProperty LoadingProperty = BindableProperty.Create(
nameof(Loading), typeof(bool), typeof(IllustDetailItem));
public ImageSource Image
{
get => (ImageSource)GetValue(ImageProperty);
set => SetValue(ImageProperty, value);
}
public bool Loading
{
get => (bool)GetValue(LoadingProperty);
set => SetValue(LoadingProperty, value);
}
}
}