Xamarin forms put login icon on top tabbed page năm 2024

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Make it simple and straightforward for new developers to get a complete app experience that is properly structured, uses the right elements, with very little effort and a clear path to being good by default.

Shell is an opinionated API at points, it does not always default every value to some .Default which may change based on the running platform. Instead it may set a value which is then respected across all platforms regardless what the platform default is.

Note: Drawing Spec moved to:

2452

Visual Treatment

Needs screenshots...

Shell Hierarchy

Understanding the Shell hierarchy at first can seem overwhelming at first. It represents a complex hierarchy and provides powerful mechanisms for minimizing the amount of boilerplate xaml required to create rich hierarchies.

Thus when first learning shell it is easiest to learn without the shortcuts first, and then introduce the shortcuts to see how to easily minimize the amount of XAML being written.

Note that all samples that follow do not use templated ShellContent's, which are discussed elsewhere in the spec. Failure to properly use ShellContents with a ContentTemplate will result in all pages being loaded at startup, which will negatively impact startup performance. These samples are for learning purposes only.

Fortunately using ShellContents with ContentTemplates is usually more concise than not using them.

No shortcuts

Many of these samples will look needlessly complex, and in reality they are. In the next section these will get simplified.

A simple one page app


  
    
  

The top bar can be hidden entirely by setting

6 on the MainPage. The Flyout would also look rather sparse in this mode and is thus disabled in this sample.

Two page app with bottom tabs


  
    
  


  
    
  

By adding a section

7 to the

8 another bottom tab appears. Settings the approriate title and icon allows control over the Tab item title and icon.

Two page app with top and bottom tabs


  
    
  


  
    
  
  
    
  

By adding a second

9 to the

7 a top tab bar is added and the pages can be flipped between when the bottom tab is selected.

Two page app using flyout navigation



  
    
  


  
    
  

The flyout is re-enabled in this sample. Here the user can switch between the two pages using the flyout as an intermediary. A header has also been added to look nice.

Using shorthand syntax

Now that all levels of the hierarchy have been shown and breifly explained, it is possible to leave most of the unneeded wrapping out when defining a hierarchy.



1 only ever contains

8s which only ever contain

7s which in turn only ever contain

9s. However there are implicit conversion operators in place to allow for automatic up-wrapping.

A simple one page app

With implicit wrapping the Page is automatically wrapped all the way up to a

8. It is not needed to write out all the intermiedate layers. The



6 and



7 from the



8 will be bound up to any implicitly generated parents.

Two page app with bottom tabs



The pages are now implicitly wrapped up into ShellContent and their own ShellSections. This results in two different tabs being created, just like before.

Two page app with top and bottom tabs



    
    

Two page app using flyout navigation


Here the implicit wrapping goes all the way up to shell item so there is no need for us to do any wrapping ourselves.

Navigation Model

Push Navigation

All navigation is based on the View’s .Navigation property. Pushes go into the current ShellSection that is displayed. This means in a push event the top tabs will go away and the bottom tabs will remain.

URI Navigation

The Shell can be navigated using the standard Navigation property as discussed above, however shell introduces a far more convenient navigation mechanism.

Navigation URI's are formatted as follows:

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

All items in the shell hierarchy have a route associated with them. If the route is not set by the developer, the route is generated at runtime. Runtime generated routes are not gauranteed to be stable across different runs of the app and thus are not useful for deep linking.

Handling the Back Button

Since Shell will be in the enviable position of not having to use native controls, all forms of back button overriding can and should be supported.

Proper handling of the back button needs to support the following features:

  • Intercepting interactions and stopping them
  • Replacing the back button with something else
  • Hiding the back button entirely when desired
  • Work for software and hardware buttons

The API needs to be granular to the page level for ease of use, but also be able to be handled further up the stack in a more general level.

Code Samples and API

Samples


  
    
  

// Flyout Item 1

  

// Flyout Item 2

  



// Flyout Item 3 // Flyout Item 4

Single Page App using Shell


  
    
  


  
    
  

0

Single Group of Tabs app [no Flyout]


  
    
  


  
    
  

1

Multiple pages in flyout with no tabs


  
    
  


  
    
  

2

Single Page Searchable App


  
    
  


  
    
  

0


  
    
  


  
    
  

4

API Definition

Shell

This is the base class for Shell's. It defines a somewhat strict navigational model however all shells must adhere to it in general. It does not include any theming or design language specific features.


  
    
  


  
    
  

5

Description

Attached Properties:

API Description SearchHandlerProperty Attached property for the definition of a page level Search capability. Can be attached at multiple points in the hierarchy. Uses some of the features defined here BackButtonBehavior Allows complete override of how the back button behaves. Applies to on-screen and physical back buttons. FlyoutBehavior Defines how the Flyout should present itself. This can be attached to

8s,

9s, or



8s to override the default behavior. NavBarVisibleProperty Property set on a



8 to define if the NavBar should be visible when it is presented SetPaddingInsetsProperty Setting this property on a



8 will cause its



    
    

4 to be set such that its content will not flow under any Shell chrome. TabBarVisibleProperty Property set on a



8 to define if the TabBar should be visible when it is presented TitleViewProperty Property set on a



8 to define the



    
    

7 ShellBackgroundColorProperty Describes the background color which should be used for the chrome elements of the Shell. This color will not fill in behind the Content of the Shell. ShellDisabledColorProperty The color to shade text/icons which are disabled ShellForegroundColorProperty The color to shade normal text/icons in the shell ShellTabBarBackgroundColorProperty Override of ShellBackgroudnColor for the TabBar. If not set ShellBackgroundColor will be used ShellTabBarDisabledColorProperty Override of ShellDisabledColor for the TabBar. If not set ShellDisabledColorProperty will be used ShellTabBarForegroundColorProperty Override of ShellForegroundColorProperty for the TabBar. If not set ShellForegroundColorProperty will be used ShellTabBarTitleColorProperty Override of ShellTitleColorProperty for the TabBar. If not set ShellTitleColorProperty will be used ShellTabBarUnselectedColorProperty Override of ShellUnselectedColorProperty for the TabBar. If not set ShellUnselectedColorProperty will be used ShellTitleColorProperty The color used for the title of the current Page ShellUnselectedColorProperty The color used for unselected text/icons in the shell chrome

Properties:

API Description CurrentItem The currently selected ShellItem CurrentState The current navigation state of the Shell. Passing this state back to GoToAsync will cause the Shell to return to navigate back state. FlyoutBackgroundColorProperty The background color of the Flyout menu FlyoutBehavior Sets the default



    
    

8 for the



1. FlyoutHeader The object used as the Header of the Flyout. If


0 is not null, this is passed as the


1 to the inflated object. If


0 is null and


3 is of type


4 it will be used directly. Otherwise it will be shown by calling ToString[] and displaying the result. FlyoutHeaderBehavior Sets the behavior of the


3 when the Flyout needs to be scrolled to show contents. FlyoutHeaderTemplate The template used to create a header for the Flyout. FlyoutIsPresented Gets or sets whether or not the Flyout is current visible GroupHeaderTemplate The


6 used to show a Group Header if a

8 requests to be displayed as a Group of Tabs in the Flyout. If null, no header is displayed. Items The primary Content of a Shell. Items define the list of items that will show in the Flyout as well as the content that will be displayed when a sidebar item is selected. ItemTemplate The


6 used to show items from the


9 collection in the Flyout. Allows the developer to control visuals in the Flyout. MenuItems A collection of

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

0s which will show up in the flyout in their own section. MenuItemTemplate The


6 to use when displayed a

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

0 in the Flyout. Route The route part to address this element when performing deep linking. RouteHost The string to place in the host portion of the URI generated when creating deep-links RouteScheme The string to place in the scheme portion of the URI generated when creating deep-links

Public Methods:

API Description GoToAsync Navigate to a

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

3. Returns a Task which will complete once the animation has completed.

Public Events:

API Description Navigating The



1 is about to perform a Navigation either due to user interaction or the developer calling an API. The developer may cancel Navigation here if possible. Navigated The



1 has completed a Navigation event.

ShellItemCollection

A collection for

8s


  
    
  


  
    
  

6

MenuItemCollection

A collection for

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

0s


  
    
  


  
    
  

7

ShellSectionCollection

A collection for

7s


  
    
  


  
    
  

8

ShellContentCollection

A collection for

9s


  
    
  


  
    
  

9

ShellNavigatingEventArgs

An


  
    
  

// Flyout Item 1

  

// Flyout Item 2

  



// Flyout Item 3 // Flyout Item 4

0 used to describe a navigation event which is about to occur. The


  
    
  

// Flyout Item 1

  

// Flyout Item 2

  



// Flyout Item 3 // Flyout Item 4

1 may also be used to cancel the navigation event if the developer desires.


  
    
  


  
    
  
  
    
  

0

Properties:

API Description Current The current NavigationState of the



1. Calling


  
    
  

// Flyout Item 1

  

// Flyout Item 2

  



// Flyout Item 3 // Flyout Item 4

3 with this

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

3 will effectively undo this navigation event. Target The state the



1 will be in after this navigation event completes. Source The type of navigation which occurred to trigger this event. There may be multiple flags set. CanCancel Whether or not the navigation event is cancellable. Not all events can be cancelled.

Public Methods:

API Description Cancel Cancels the current navigation event. Returns true if the cancellation was succesful.

ShellNavigatedEventArgs


  
    
  


  
    
  
  
    
  

1

Properties:

API Description Previous The prior NavigationState of the



1. Current The new state the



1 is in when this navigation event completed. Source The type of navigation which occurred to trigger this event. There may be multiple flags set.

ShellNavigationState


  
    
  


  
    
  
  
    
  

2

Properties:

API Description Location The Uri which describes the navigation state of the



1

Constructors:

API Description [void] Creates a new

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

3 with a null Location [String] Creates a new

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

3 with the Location set to the supplied


  
    
  


  
    
  

01 [Uri] Creates a new

[Shell.RouteScheme]://[Shell.RouteHost]/[Shell]/[ShellItem]/[ShellSection]/[ShellContent]/[NavStack1]/[NavStack2]...

3 with the Location set to the supplied


  
    
  


  
    
  

03

ShellNavigationSource


  
    
  


  
    
  
  
    
  

3

BaseShellItem


  
    
  


  
    
  
  
    
  

4

Properties:

API Description FlyoutIcon The default icon to use when displayed in the Flyout. Will default to Icon if not set. Icon The icon to display in parts of the chrome which are not the Flyout. IsChecked If the


  
    
  


  
    
  

04 is currently checked in the Flyout [and thus should be highlighted] IsEnabled If the the


  
    
  


  
    
  

04 is selectable in the chrome Route Equivelant to setting Routing.Route Title The Title to display in the UI

ShellGroupItem


  
    
  


  
    
  
  
    
  

5

Properties:

API Description FlyoutDisplayOptions Controls how this item and its children are displayed in the flyout

ShellItem


  
    
  


  
    
  
  
    
  

6

Properties:

API Description CurrentItem The selected

7. Items The


  
    
  


  
    
  

07 which is the primary content of a ShellItem. This collection defines all the tabs within a ShellItem.

ShellSection


  
    
  


  
    
  
  
    
  

7

Properties:

API Description CurrentItem The selected

9 of the ShellSection. Items The


  
    
  


  
    
  

09 which is the root content of the ShellSection. Stack The current pushed navigation stack on the ShellSection.

Methods:

API Description GoToAsync Used by deep-linking to navigate to a known location. Should not need to be called directly in most cases. GetNavigationStack Returns the current navigation stack OnInsertPageBefore Called when the


  
    
  


  
    
  

10 interfaces


  
    
  


  
    
  

11 method is called OnPopAsync Called when the


  
    
  


  
    
  

10 interfaces


  
    
  


  
    
  

13 method is called OnPopToRootAsync Called when the


  
    
  


  
    
  

10 interfaces


  
    
  


  
    
  

15 method is called OnPushAsync Called when the


  
    
  


  
    
  

10 interfaces


  
    
  


  
    
  

17 method is called OnRemovePage Called when the


  
    
  


  
    
  

10 interfaces


  
    
  


  
    
  

19 method is called

ShellContent


  
    
  


  
    
  
  
    
  

8

Properties:

API Description Content The Content of a ShellContent. Usually a


  
    
  


  
    
  

20 or the


1 of the



8 inflated by the


  
    
  


  
    
  

23 ContentTemplate Used to dynamically inflate the content of the

9. The


  
    
  


  
    
  

25 property will be set as the


1 after inflation. MenuItems The items to display in the Flyout when this ShellContent is the presented page

SearchHandler


  
    
  


  
    
  
  
    
  

9

Properties:

API Description ClearIconHelpText The accessible help text for the clear icon ClearIconNameProperty The name of the clear icon for usage with screen readers ClearIcon The icon displayed to clear the contents of the search box. ClearPlaceholderCommandParameter The paramter for the


  
    
  


  
    
  

27 ClearPlacehodlerCommand The command to execute when the ClearPlaceholder icon is tapped ClearPlaceholderEnabled The enabled state of the ClearPlaceholderIcon. Default is true. ClearPlaceholderHelpText The accessible help text for the clear placeholder icon ClearPlaceholderIcon The icon displayed in the


  
    
  


  
    
  

28 location when the search box is empty. ClearPlaceholderName The name of the clear placeholder icon for usage with screen readers CommandParameter The parameter for the


  
    
  


  
    
  

29 Command The


  
    
  


  
    
  

30 to execute when a query is confirmed DisplayMemberPath The name or path of the property that is displayed for each the data item in the


  
    
  


  
    
  

31. IsSearchEnabled Controls the enabled state of the search box. ItemsSource A collection of items to display in the suggestion area. ItemTemplate A template for the items displayed in the suggestion area. Placeholder A string to display when the search box is empty. QueryIconHelpTextProperty The accessible help text for the query icon QueryIconNameProperty The name of the query icon for usage with screen readers QueryIcon The icon used to indicate to the user that search is available Query The current string in the search box. SearchBoxVisibility Defines the visibility of the search box in the



1s chrome. ShowsResults Determines if search results should be expected on text entry

Protected Methods:

API Description OnClearPlaceholderClicked Called whenever the ClearPlaceholder icon has been pressed. OnItemSelected Called whenever a search result is pressed by the user OnQueryConfirmed Called whenever the user pressed enter or confirms their entry in the search box. OnQueryChanged Called when the


  
    
  


  
    
  

33 is changed.

SearchBoxVisiblity



  
    
  


  
    
  

0

Value Description Hidden The search box is not visible or accessible. Collapsable The search box is hidden until the user performs an action to reveal it. Expanded The search box is visible as a fully expanded entry.

BackButtonBehavior



  
    
  


  
    
  

1

API Description IconOverride Changes the Icon used for the back button. TextOverride Changes the Text used to indicate backwards navigation if text is used. Command Provides a replacement command to invoke when the back button is pressed. CommandParameter The command parameter used with


  
    
  


  
    
  

29

FlyoutDisplayOptions

Determines how the


  
    
  


  
    
  

35 should display in the FlyoutMenu.



  
    
  


  
    
  

2

Value Description AsSingleItem The


  
    
  


  
    
  

35 will be visible as a single entry in the Flyout. AsMultipleItems The


  
    
  


  
    
  

35 will be visible as a group of items, one for each child in the Flyout.

FlyoutHeaderBehavior

Controls the behavior of the FlyoutHeader when scrolling.



  
    
  


  
    
  

3

Value Description Default Platform default behavior. Fixed Header remains visible and unchanged at all times Scroll Header scrolls out of view as user scrolls menu CollapseOnScroll Header collapses to title only as user scrolls

FlyoutBehavior



  
    
  


  
    
  

4

Value Description Disabled The flyout cannot be acccessed by the user. Flyout The Flyout is works as a normal flyout which can be open/closed by the user. Locked The Flyout is locked out and cannot be closed by the user, it does not overalp content.

DataTemplateExtension

This extension quickly converts a type into a ControlTemplate. This is useful for instances where the template would otherwise be specified as



  
    
  


  
    
  

5

This can then be condensed down to



  
    
  


  
    
  

6



  
    
  


  
    
  

7



  
    
  


  
    
  

8

Odds and Ends

What happens when you select a tab in Flyout which has been pushed to?

This is the equivalent of focusing the tab and calling PopToRoot on it.

What happens when I switch ShellItems and there are items on the backstack of a ShellContent of the old ShellItem

If the old ShellItem is templated, the back stack is lost. If the ShellItem is not templated the BackStack stays intact and when switching back to the old ShellItem the backstack will be properly reflected. Switching back may clear the backstack however as indicated in the above answer.

Effecient loading of pages

A major problem with using the Shell is the ease by which a user can end up loading all pages at the start of their application run. This large frontloaded allocation can result in quite poor startup performance if a large number of content pages are needed. In order to fix this templating should be employed when possible.

Templated ShellContents

Templating shell tab items is the most granular form of templating available, it is fortunately also the easiest to do. Take the following shell.



  
    
  


  
    
  

9

When this Shell loads, all 9 pages will be inflated at once. This is because no templating is employed. To employ basic templating we can convert this into:

0

Pages are now only loaded as needed and can be unloaded as needed as well. If needed the ShellItem's themselves can also be templated with a collection and a DataTemplateSelector which prevents even the ShellContents from having to be loaded eagerly, however this is largely unneeded and templating ShellItem is more useful for Shells that have ShellItems with large numbers of otherwise similar tabs. Templating the ShellContent should be the key area to provide templating for performance concerns.

Reconstructing the Google Play Store User Interface

Please note this is not intended to be a demo of the best way to code an application, but really the most concise format to shove together the UI for GPS. It also makes no attempt to virtualize the relevant pages by using ViewModels and DataTemplateSelector's. This means this would be quite bad performing as all pages would be loaded at app start. Reader is warned.

All page content is assumed to be working right, this is only to get the general idea of the chrome.

Shell.xaml

A proper implementation of this would use ShellItems for every page and set the ItemsSource and ItemTemplate. This would allow each page to only be loaded once it is needed and unloaded when no longer needed.

1

The store pages

2

3

And to add the search bar.

4

And so on and so on setting the colors and the content correctly.

For pages like the Settings page where the flyout should not be accessible until the back button is pressed:

5

TODO

  • Add API for search box
  • Add API for ContentSafeArea handling
  • Add API for floating menu
  • Add API for window menu items
  • Add API for snackbar
  • Add API for navigation interruption
  • Add API for bottom sheet
  • Add API to position FAB
  • Add stories to make navigation ideas clearer [partially done]
  • Add LeftBarButton style API
  • Add mechanism for getting Back Stack from ShellContent
  • Add API for changing color of the ribbon based on selected tab
  • Add optional suggestion support for SearchHandler
  • Add support for configuring always expanded search bar vs search bar as icon
  • Add API for getting the "Current" page from the MaterialShell class. Needed for some navigation scenarios.
  • Add API for saving "states" to the back stack
  • Add API to block flyout from coming out
  • Add API for "submenu" items for ShellContent's ala GPS -> Music -> Open Music app
  • Add API for CancelPlaceholder Command and Icon [usually used for microphone icon for voice search]
  • Segue API
  • Work out what to do with INavigation
  • Expand Bottom Sheet API to match Google Maps capabilities
  • API to handle Flyout presentation
  • API to disable Flyout gesture when needed
  • Large title API
  • Transitions API

Issues

ISearchHandler [FIXED]

There is a lot this interface is doing and worse it's probably going to need to be expanded as time goes on. Therefor it stands to reason that it should probably instead be an abstract base class the user can implement. This unfortunate means yet another object allocation. However it maintains flexibility in the future. It is likely this change will happen.

Floating Menu

The attachment API is a bit heavy and perhaps too confusing for users. Worse it might not map very well to all platforms to make sure the attachment works with animations. More work is required to validate this API.

Chủ Đề