Skip to content

Commit

Permalink
[Shell] Add FlyoutIcon (xamarin#5567) fixes xamarin#4766 fixes xamari…
Browse files Browse the repository at this point in the history
…n#4767 fixes xamarin#4845 fixes xamarin#5219

* [Controls]  Add repo for shell issue

* [iOS] Allow specify SetPaddingInsets on the ShellContent

* [iOS,Shell] Fix issue when disposing ToolbarItems  of old page

* [Controls] Add demo repo for xamarin#5466

* [Shell,Core] Fix navigating to a registered route

* [Shell,Core] Add better exception messages for wrong or non existing content fixes xamarin#5081

* [Core,Shell,iOS,Android] Add FlyoutIcon property

* [Controls] Make shell sample work on Android

* [Controls,Android] Add ImageSource support to FlyoutIcon

* [Android]Allow to set text on the back button

* [Android] Create default text back button

* [Controls] Add example to push with back button behavior

* [Android] Fix back button tint color

* [Android] Cleanup and refactor UpdateDrawerArrow

* Update Xamarin.Forms.Platform.Android/Renderers/ShellToolbarTracker.cs

Co-Authored-By: rmarinho <me@ruimarinho.net>

* [iOS,Shell] Fix go back (Pop) when proving BackButtonBehavior

* [iOS] Check the ParentViewController since we were push to it

* [Android,iOS,Shell] Remove extra code implement feedback

* removed old code

* minor cleanup
  • Loading branch information
rmarinho authored and Alexey Maltsev committed Jun 15, 2019
1 parent 6e8eece commit 9cc0223
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -382,4 +382,4 @@
</CreateItem>
<Copy SourceFiles="@(MapsKey)" DestinationFiles="Properties\MapsKey.cs" Condition="!Exists('Properties\MapsKey.cs')" />
</Target>
</Project>
</Project>
2 changes: 1 addition & 1 deletion Xamarin.Forms.Controls/XamStore/StoreShell.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,4 @@
<MenuItem Text="Parent Guide" />
<MenuItem Text="About Xam Store" />
</Shell.MenuItems>
</Shell>
</Shell>
27 changes: 23 additions & 4 deletions Xamarin.Forms.Controls/XamStore/StoreShell.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,30 @@ namespace Xamarin.Forms.Controls.XamStore
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class StoreShell : Shell
{
public StoreShell ()
public StoreShell()
{
InitializeComponent ();

CurrentItem = _storeItem;
InitializeComponent();
var fontFamily = "";
switch (Device.RuntimePlatform)
{
case Device.iOS:
fontFamily = "Ionicons";
break;
case Device.UWP:
fontFamily = "Assets/Fonts/ionicons.ttf#ionicons";
break;
case Device.Android:
default:
fontFamily = "fonts/ionicons.ttf#";
break;
}
FlyoutIcon = new FontImageSource
{
Glyph = "\uf2fb",
FontFamily = fontFamily,
Size = 20
};
CurrentItem = _storeItem;
Routing.RegisterRoute("demo", typeof(DemoShellPage));
Routing.RegisterRoute("demo/demo", typeof(DemoShellPage));
}
Expand Down
2 changes: 1 addition & 1 deletion Xamarin.Forms.Controls/XamStore/Views/DemoShellPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
StyleClass="MainTab"
HorizontalOptions="FillAndExpand"
VerticalOptions="Fill"
Image="button_bookmark.png"
Image="icon_bookmark.png"
Command="{Binding ToggleCommand}"
CommandParameter="bookmarked">
<Button.Triggers>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
Expand Down
17 changes: 15 additions & 2 deletions Xamarin.Forms.Controls/XamStore/Views/StorePages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private Button MakeButton (string title, Action callback)
public BasePage(string title, Color tint)
{
Title = title;

Shell.SetShellForegroundColor(this, tint);
var grid = new Grid()
{
Padding = 20,
Expand Down Expand Up @@ -209,7 +209,7 @@ public BasePage(string title, Color tint)
Navigation.PushAsync(page);
}),
2, 14);

grid.Children.Add(MakeButton("Show Alert",
async () => {
var result = await DisplayAlert("Title", "Message", "Ok", "Cancel");
Expand All @@ -220,6 +220,19 @@ public BasePage(string title, Color tint)
async () => await Shell.CurrentShell.GoToAsync("demo", true)),
1, 15);

grid.Children.Add(MakeButton("Go Back with Text",
async () => {
var page = (Page)Activator.CreateInstance(GetType());
Shell.SetShellForegroundColor(page, Color.Pink);
Shell.SetBackButtonBehavior(page, new BackButtonBehavior()
{
//IconOverride = "calculator.png",

TextOverride = "back"
});
await Navigation.PushAsync(page);
}),2, 15);

grid.Children.Add(new Label {
Text = "Navigate to",
VerticalOptions = LayoutOptions.CenterAndExpand
Expand Down
2 changes: 2 additions & 0 deletions Xamarin.Forms.Core/Shell/IShellController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public interface IShellController : IPageController

View FlyoutHeader { get; }

ImageSource FlyoutIcon { get; }

void AddAppearanceObserver(IAppearanceObserver observer, Element pivot);

void AddFlyoutBehaviorObserver(IFlyoutBehaviorObserver observer);
Expand Down
10 changes: 10 additions & 0 deletions Xamarin.Forms.Core/Shell/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ ShellNavigationState GetNavigationState(ShellItem shellItem, ShellSection shellS
public static readonly BindableProperty MenuItemTemplateProperty =
BindableProperty.Create(nameof(MenuItemTemplate), typeof(DataTemplate), typeof(Shell), null, BindingMode.OneTime);

public static readonly BindableProperty FlyoutIconProperty =
BindableProperty.Create(nameof(FlyoutIcon), typeof(ImageSource), typeof(Shell), null);

ShellNavigatedEventArgs _accumulatedEvent;
bool _accumulateNavigatedEvents;
View _flyoutHeaderView;
Expand All @@ -587,6 +590,13 @@ internal static void VerifyShellFlagEnabled(string constructorHint = null, [Call
public event EventHandler<ShellNavigatedEventArgs> Navigated;
public event EventHandler<ShellNavigatingEventArgs> Navigating;


public ImageSource FlyoutIcon
{
get => (ImageSource)GetValue(FlyoutIconProperty);
set => SetValue(FlyoutIconProperty, value);
}

public ShellItem CurrentItem {
get => (ShellItem)GetValue(CurrentItemProperty);
set => SetValue(CurrentItemProperty, value);
Expand Down
19 changes: 19 additions & 0 deletions Xamarin.Forms.Platform.Android/Forms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,25 @@ internal static bool IsMarshmallowOrNewer
}
}

public static float GetFontSizeNormal(Context context)
{
float size = 50;
if (!IsLollipopOrNewer)
return size;

// Android 5.0+
//this doesn't seem to work
using (var value = new TypedValue())
{
if (context.Theme.ResolveAttribute(Resource.Attribute.TextSize, value, true))
{
size = value.Data;
}
}

return size;
}

public static Color GetColorButtonNormal(Context context)
{
if (!_ColorButtonNormalSet)
Expand Down
175 changes: 142 additions & 33 deletions Xamarin.Forms.Platform.Android/Renderers/ShellToolbarTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Threading.Tasks;
using ActionBarDrawerToggle = Android.Support.V7.App.ActionBarDrawerToggle;
using AView = Android.Views.View;
using LP = Android.Views.ViewGroup.LayoutParams;
Expand Down Expand Up @@ -130,7 +131,7 @@ protected override void Dispose(bool disposing)
{
UpdateTitleView(_shellContext.AndroidContext, _toolbar, null);

_drawerToggle.Dispose();
_drawerToggle?.Dispose();
if (_searchView != null)
{
_searchView.View.RemoveFromParent();
Expand Down Expand Up @@ -235,51 +236,113 @@ protected virtual async void UpdateLeftBarButtonItem(Context context, Toolbar to
var backButtonHandler = Shell.GetBackButtonBehavior(page);
toolbar.SetNavigationOnClickListener(this);

var activity = (FormsAppCompatActivity)context;

if (backButtonHandler != null)
{
using (var icon = await context.GetFormsDrawable(backButtonHandler.IconOverride))
using (var mutatedIcon = icon.GetConstantState().NewDrawable().Mutate())
await UpdateDrawerArrowFromBackButtonBehavior(context, toolbar, drawerLayout, backButtonHandler, activity);
}
else
{
await UpdateDrawerArrow(context, toolbar, drawerLayout, activity);
}
}

protected virtual async Task UpdateDrawerArrow(Context context, Toolbar toolbar, DrawerLayout drawerLayout, FormsAppCompatActivity activity)
{
if (_drawerToggle == null)
{
_drawerToggle = new ActionBarDrawerToggle((Activity)context, drawerLayout, toolbar,
R.String.Ok, R.String.Ok)
{
mutatedIcon.SetColorFilter(TintColor.ToAndroid(Color.White), PorterDuff.Mode.SrcAtop);
toolbar.NavigationIcon = mutatedIcon;
ToolbarNavigationClickListener = this,
};

await UpdateDrawerArrowFromFlyoutIcon(context, _drawerToggle);

_drawerToggle.DrawerSlideAnimationEnabled = false;
drawerLayout.AddDrawerListener(_drawerToggle);
}

if (CanNavigateBack)
{
_drawerToggle.DrawerIndicatorEnabled = false;
using (var icon = new DrawerArrowDrawable(activity.SupportActionBar.ThemedContext))
{
icon.SetColorFilter(TintColor.ToAndroid(Color.White), PorterDuff.Mode.SrcAtop);
icon.Progress = 1;
toolbar.NavigationIcon = icon;
}
}
else if (_flyoutBehavior == FlyoutBehavior.Flyout)
{
toolbar.NavigationIcon = null;
var drawable = _drawerToggle.DrawerArrowDrawable;
drawable.SetColorFilter(TintColor.ToAndroid(Color.White), PorterDuff.Mode.SrcAtop);
_drawerToggle.DrawerIndicatorEnabled = true;
}
else
{
var activity = (FormsAppCompatActivity)context;
if (_drawerToggle == null)
_drawerToggle.DrawerIndicatorEnabled = false;
}
_drawerToggle.SyncState();
}

protected virtual async Task UpdateDrawerArrowFromBackButtonBehavior(Context context, Toolbar toolbar, DrawerLayout drawerLayout, BackButtonBehavior backButtonHandler, FormsAppCompatActivity activity)
{
var behavior = backButtonHandler;
var command = behavior.Command;
var commandParameter = behavior.CommandParameter;
var image = behavior.IconOverride;
var text = behavior.TextOverride;
var enabled = behavior.IsEnabled;

Drawable icon = null;

if (image != null)
icon = await context.GetFormsDrawable(image);

if (text != null)
icon = new FlyoutIconDrawerDrawable(context, TintColor, icon, text);

if (CanNavigateBack && icon == null)
{
icon = new DrawerArrowDrawable(activity.SupportActionBar.ThemedContext);
(icon as DrawerArrowDrawable).Progress = 1;
}

var iconState = icon.GetConstantState();
if (iconState != null)
{
using (var mutatedIcon = iconState.NewDrawable().Mutate())
{
_drawerToggle = new ActionBarDrawerToggle(context.GetActivity(), drawerLayout, toolbar,
R.String.Ok, R.String.Ok)
{
ToolbarNavigationClickListener = this,
};
_drawerToggle.DrawerSlideAnimationEnabled = false;
drawerLayout.AddDrawerListener(_drawerToggle);
mutatedIcon.SetColorFilter(TintColor.ToAndroid(Color.White), PorterDuff.Mode.SrcAtop);
toolbar.NavigationIcon = mutatedIcon;
}
}
else
{
toolbar.NavigationIcon = icon;
}
}

if (CanNavigateBack)
protected virtual async Task UpdateDrawerArrowFromFlyoutIcon(Context context, ActionBarDrawerToggle actionBarDrawerToggle)
{
Element item = Page;
ImageSource icon = null;
while (!Application.IsApplicationOrNull(item))
{
if (item is IShellController shell)
{
_drawerToggle.DrawerIndicatorEnabled = false;
using (var icon = new DrawerArrowDrawable(activity.SupportActionBar.ThemedContext))
icon = shell.FlyoutIcon;
if (icon != null)
{
icon.SetColorFilter(TintColor.ToAndroid(Color.White), PorterDuff.Mode.SrcAtop);
icon.Progress = 1;
toolbar.NavigationIcon = icon;
var drawable = await context.GetFormsDrawable(icon);
actionBarDrawerToggle.DrawerArrowDrawable = new FlyoutIconDrawerDrawable(context, TintColor, drawable, null);
}
return;
}
else if (_flyoutBehavior == FlyoutBehavior.Flyout)
{
toolbar.NavigationIcon = null;
using (var drawable = _drawerToggle.DrawerArrowDrawable)
drawable.SetColorFilter(TintColor.ToAndroid(Color.White), PorterDuff.Mode.SrcAtop);
_drawerToggle.DrawerIndicatorEnabled = true;
}
else
{
_drawerToggle.DrawerIndicatorEnabled = false;
}
_drawerToggle.SyncState();
item = item?.Parent;
}
}

Expand Down Expand Up @@ -452,5 +515,51 @@ void UpdateToolbarItems()
{
UpdateToolbarItems(_toolbar, Page);
}

class FlyoutIconDrawerDrawable : DrawerArrowDrawable
{
Drawable _iconBitmap;
string _text;
Color _defaultColor;
float _defaultSize;

Color _pressedBackgroundColor => _defaultColor.AddLuminosity(-.12);//<item name="highlight_alpha_material_light" format="float" type="dimen">0.12</item>

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing && _iconBitmap != null)
{
_iconBitmap.Dispose();
}
}

public FlyoutIconDrawerDrawable(Context context, Color defaultColor, Drawable icon, string text) : base(context)
{
_defaultColor = defaultColor;
_defaultSize = Forms.GetFontSizeNormal(context);
_iconBitmap = icon;
_text = text;
}

public override void Draw(Canvas canvas)
{
bool pressed = false;
if (_iconBitmap != null)
{
_iconBitmap.SetBounds(Bounds.Left, Bounds.Top, Bounds.Right, Bounds.Bottom);
_iconBitmap.Draw(canvas);
}
else if (!string.IsNullOrEmpty(_text))
{
var paint = new Paint { AntiAlias = true };
paint.TextSize = _defaultSize;
paint.Color = pressed ? _pressedBackgroundColor.ToAndroid() : _defaultColor.ToAndroid();
paint.SetStyle(Paint.Style.Fill);
var y = (Bounds.Height() + paint.TextSize) / 2;
canvas.DrawText(_text, 0, y, paint);
}
}
}
}
}
}
Loading

0 comments on commit 9cc0223

Please sign in to comment.