<p>Especificaciones de Xamarin.Forms.Shell</p>

Creado en 10 abr. 2018  ·  199Comentarios  ·  Fuente: xamarin/Xamarin.Forms

Especificaciones de shell de Xamarin.Forms

Haga que sea simple y directo para que los nuevos desarrolladores obtengan una experiencia de aplicación completa que esté estructurada correctamente, use los elementos correctos, con muy poco esfuerzo y un camino claro para ser bueno por defecto.

Shell es una API obstinada en algunos puntos, no siempre establece todos los valores predeterminados en algunos valores predeterminados que pueden cambiar según la plataforma en ejecución. En su lugar, puede establecer un valor que luego se respete en todas las plataformas, independientemente de cuál sea la plataforma predeterminada.

Nota: Especificaciones de dibujo movidas a: # 2452

Tratamiento visual

Necesita capturas de pantalla ...

Jerarquía de Shell

Comprender la jerarquía de Shell al principio puede parecer abrumador al principio. Representa una jerarquía compleja y proporciona mecanismos poderosos para minimizar la cantidad de xaml estándar que se requiere para crear jerarquías ricas.

Por lo tanto, cuando se aprende por primera vez el shell, es más fácil aprender sin los atajos primero y luego introducir los atajos para ver cómo minimizar fácilmente la cantidad de XAML que se escribe.

Tenga en cuenta que todas las muestras que siguen no utilizan ShellContent con plantilla, que se analizan en otra parte de la especificación. Si no se usa correctamente ShellContents con ContentTemplate, todas las páginas se cargarán al inicio, lo que afectará negativamente el rendimiento de inicio. Estas muestras son solo para fines de aprendizaje.

Afortunadamente, usar ShellContents con ContentTemplates suele ser más conciso que no usarlos.

Sin atajos

Muchas de estas muestras parecerán innecesariamente complejas, y en realidad lo son. En la siguiente sección, estos se simplificarán.

Una aplicación simple de una página

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       FlyoutBehavior="Disabled"
       x:Class="MyStore.Shell">

  <ShellItem>
    <ShellSection>
      <ShellContent>
        <local:HomePage />
      </ShellContent>
    </ShellSection>
  </ShellItem>
</Shell>

step1

La barra superior se puede ocultar completamente configurando Shell.NavBarVisible="false" en MainPage. El Flyout también se vería bastante escaso en este modo y, por lo tanto, está desactivado en esta muestra.

Aplicación de dos páginas con pestañas inferiores

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       FlyoutBehavior="Disabled"
       x:Class="MyStore.Shell">

  <ShellItem>

    <ShellSection Title="Home" Icon="home.png">
      <ShellContent>
        <local:HomePage />
      </ShellContent>
    </ShellSection>

    <ShellSection Title="Notifications" Icon="bell.png">
      <ShellContent>
        <local:NotificationsPage />
      </ShellContent>
    </ShellSection>

  </ShellItem>
</Shell>

step2

Al agregar una sección ShellSection al ShellItem aparece otra pestaña inferior. La configuración del título y el icono apropiados permite controlar el título y el icono del elemento de la pestaña.

Aplicación de dos páginas con pestañas superior e inferior

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       FlyoutBehavior="Disabled"
       x:Class="MyStore.Shell">

  <ShellItem>

    <ShellSection Title="Home" Icon="home.png">
      <ShellContent>
        <local:HomePage />
      </ShellContent>
    </ShellSection>

    <ShellSection Title="Notifications" Icon="bell.png">

      <ShellContent Title="Recent">
        <local:NotificationsPage />
      </ShellContent>

      <ShellContent Title="Alert Settings">
        <local:SettingsPage />
      </ShellContent>

    </ShellSection>

  </ShellItem>
</Shell>

step3

Al agregar un segundo ShellContent al ShellSection , se agrega una barra de pestañas superior y las páginas se pueden cambiar cuando se selecciona la pestaña inferior.

Aplicación de dos páginas con navegación flotante

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       x:Class="MyStore.Shell">

  <Shell.FlyoutHeader>
    <local:FlyoutHeader />
  </Shell.FlyoutHeader>

  <ShellItem Title="Home" Icon="home.png">
    <ShellSection>
      <ShellContent>
        <local:HomePage />
      </ShellContent>
    </ShellSection>
  </ShellItem>

  <ShellItem Title="Notifications" Icon="bell.png">
    <ShellSection>
      <ShellContent>
        <local:NotificationsPage />
      </ShellContent>
    </ShellSection>
  </ShellItem>
</Shell>

step4

El control flotante se vuelve a habilitar en este ejemplo. Aquí, el usuario puede cambiar entre las dos páginas utilizando el menú desplegable como intermediario. También se ha agregado un encabezado para que se vea bien.

Usar sintaxis taquigráfica

Ahora que se han mostrado y explicado brevemente todos los niveles de la jerarquía, es posible dejar la mayor parte de los detalles innecesarios al definir una jerarquía. Shell solo contiene ShellItem s que solo contienen ShellSection s que a su vez solo contienen ShellContent s. Sin embargo, existen operadores de conversión implícitos para permitir el ajuste automático.

Una aplicación simple de una página

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       FlyoutBehavior="Disabled"
       x:Class="MyStore.Shell">

  <local:HomePage />
</Shell>

Con el ajuste implícito, la página se ajusta automáticamente hasta ShellItem . No es necesario escribir todas las capas intermedias. Los Title y Icon de Page estarán vinculados a cualquier padre generado implícitamente.

Aplicación de dos páginas con pestañas inferiores

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       FlyoutBehavior="Disabled"
       x:Class="MyStore.Shell">

  <ShellItem>
    <local:HomePage Icon="home.png" />
    <local:NotificationsPage Icon="bell.png" />
  </ShellItem>
</Shell>

Las páginas ahora están envueltas implícitamente en ShellContent y sus propias ShellSections. Esto da como resultado la creación de dos pestañas diferentes, como antes.

Aplicación de dos páginas con pestañas superior e inferior

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       FlyoutBehavior="Disabled"
       x:Class="MyStore.Shell">

  <ShellItem>
    <local:HomePage Icon="home.png" />

    <ShellSection Title="Notifications" Icon="bell.png">
        <local:NotificationsPage />
        <local:SettingsPage />
    </ShellSection>
  </ShellItem>
</Shell>

Aplicación de dos páginas con navegación flotante

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:local="clr-namespace:MyStore"
       x:Class="MyStore.Shell">

  <Shell.FlyoutHeader>
    <local:FlyoutHeader />
  </Shell.FlyoutHeader>

  <local:HomePage Icon="home.png" />
  <local:NotificationsPage Icon="bell.png" />
</Shell>

Aquí, el envoltorio implícito llega hasta el elemento shell, por lo que no es necesario que lo hagamos nosotros mismos.

Modelo de navegación

Navegación push

Toda la navegación se basa en la propiedad .Navigation de la vista. Los empujes van a la ShellSection actual que se muestra. Esto significa que en un evento de empuje, las pestañas superiores desaparecerán y las pestañas inferiores permanecerán.

Navegación URI

Se puede navegar por el Shell utilizando la propiedad de navegación estándar como se discutió anteriormente, sin embargo, el shell presenta un mecanismo de navegación mucho más conveniente.

Los URI de navegación tienen el siguiente formato:

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

Todos los elementos de la jerarquía de shell tienen una ruta asociada. Si el desarrollador no establece la ruta, la ruta se genera en tiempo de ejecución. No se garantiza que las rutas generadas en tiempo de ejecución sean estables en diferentes ejecuciones de la aplicación y, por lo tanto, no son útiles para enlaces profundos.

Manejo del botón Atrás

Dado que Shell estará en la envidiable posición de no tener que usar controles nativos, todas las formas de anulación del botón de retroceso pueden y deben ser compatibles.

El manejo adecuado del botón de retroceso debe admitir las siguientes características:

  • Interceptar interacciones y detenerlas
  • Reemplazar el botón de retroceso con otra cosa
  • Ocultar el botón de retroceso por completo cuando lo desee
  • Trabajar para botones de software y hardware

La API debe ser granular al nivel de la página para facilitar su uso, pero también debe poder manejarse más arriba en la pila en un nivel más general.

Muestras de código y API

Muestras

<Shell>
  <Shell.FlyoutHeaderTemplate>
    <DataTemplate>
      <Grid>
        <Label Text="{x:Bind HeaderText}" />
      </Grid>
    </DataTemplate>
  </Shell.FlyoutHeaderTemplate>

  // Flyout Item 1
  <ShellItem Title="My music" ItemsSource="{x:Bind MyMusicModels}" TabLocation="Bottom">
    <ShellItem.ItemTemplate>
      <local:MyMusicItemTemplateSelection />
    </ShellItem.ItemTemplate>
  </ShellItem>

  // Flyout Item 2
  <ShellItem Title="Home" Icon="home.png" GroupBehavior="ShowTabs">
    <ShellContent Title="My Friends">
      <local:FriendsPage />
    </ShellContent>
    <local:FeedPage />
    <local:ProfilePage />
  </ShellItem>

  // Flyout Item 3
  <local:SettingsPage />

  // Flyout Item 4
  <MenuItem Text="Log Out" Command="{x:Bind LogOutCommand}" />
</Shell>

Aplicación de una sola página usando Shell

<Shell FlyoutVisibility="Disabled">
  <local:MyPage />
</Shell>

Aplicación de grupo único de pestañas (sin menú desplegable)

<Shell FlyoutVisibility="Disabled">
  <ShellItem>
    <local:MyPage />
    <local:MySecondPage />
    <local:MyThirdPage />
  </ShellItem>
</Shell>

Varias páginas flotantes sin pestañas

<Shell FlyoutVisibility="Disabled">
  <local:MyPage />
  <local:MySecondPage />
  <local:MyThirdPage />
</Shell>

Aplicación de búsqueda de una sola página

<Shell FlyoutVisibility="Disabled">
  <local:MyPage />
</Shell>

`` csharp
clase pública MyPage: ContentPage
{
clase pública MyPageSearchHandler: SearchHandler
{
public MyPageHandler ()
{
SearchBoxVisibility = SearchBoxVisibility.Collapsed;
IsSearchEnabled = true;
Placeholder = "¡Búscame!";
}

protected override async void OnSearchConfirmed (string query)
{
  IsSearching = true;

  await PerformSearch (query);
  UpdateResults ();

  IsSearching = false;
}

protected override void OnSearchChanged (string oldValue, string newValue)
{
  // Do nothing, we will wait for confirmation
}

}

public MyPage ()
{
Shell.SetSearchHandler (esto, nuevo MyPageSearchHandler ());
}
}

## 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.

```csharp
[ContentProperty("Items")]
public class Shell : Page, IShellController
{
  // Attached Properties
  public static readonly BindableProperty BackButtonBehaviorProperty;
  public static readonly BindableProperty FlyoutBehaviorProperty;
  public static readonly BindableProperty NavBarVisibleProperty;
  public static readonly BindableProperty SearchHandlerProperty;
  public static readonly BindableProperty SetPaddingInsetsProperty;
  public static readonly BindableProperty TabBarVisibleProperty;
  public static readonly BindableProperty TitleViewProperty;
  public static readonly BindableProperty ShellBackgroundColorProperty;
  public static readonly BindableProperty ShellDisabledColorProperty;
  public static readonly BindableProperty ShellForegroundColorProperty;
  public static readonly BindableProperty ShellTabBarBackgroundColorProperty;
  public static readonly BindableProperty ShellTabBarDisabledColorProperty;
  public static readonly BindableProperty ShellTabBarForegroundColorProperty;
  public static readonly BindableProperty ShellTabBarTitleColorProperty;
  public static readonly BindableProperty ShellTabBarUnselectedColorProperty;
  public static readonly BindableProperty ShellTitleColorProperty;
  public static readonly BindableProperty ShellUnselectedColorProperty;

  public static BackButtonBehavior GetBackButtonBehavior(BindableObject obj);
  public static FlyoutBehavior GetFlyoutBehavior(BindableObject obj);
  public static bool GetNavBarVisible(BindableObject obj);
  public static SearchHandler GetSearchHandler(BindableObject obj);
  public static bool GetSetPaddingInsets(BindableObject obj);
  public static bool GetTabBarVisible(BindableObject obj);
  public static View GetTitleView(BindableObject obj);
  public static void SetBackButtonBehavior(BindableObject obj, BackButtonBehavior behavior);
  public static void SetFlyoutBehavior(BindableObject obj, FlyoutBehavior value);
  public static void SetNavBarVisible(BindableObject obj, bool value);
  public static void SetSearchHandler(BindableObject obj, SearchHandler handler);
  public static void SetSetPaddingInsets(BindableObject obj, bool value);
  public static void SetTabBarVisible(BindableObject obj, bool value);
  public static void SetTitleView(BindableObject obj, View value);
  public static Color GetShellBackgroundColor(BindableObject obj);
  public static Color GetShellDisabledColor(BindableObject obj);
  public static Color GetShellForegroundColor(BindableObject obj);
  public static Color GetShellTabBarBackgroundColor(BindableObject obj);
  public static Color GetShellTabBarDisabledColor(BindableObject obj);
  public static Color GetShellTabBarForegroundColor(BindableObject obj);
  public static Color GetShellTabBarTitleColor(BindableObject obj);
  public static Color GetShellTabBarUnselectedColor(BindableObject obj);
  public static Color GetShellTitleColor(BindableObject obj);
  public static Color GetShellUnselectedColor(BindableObject obj);
  public static void SetShellBackgroundColor(BindableObject obj, Color value);
  public static void SetShellDisabledColor(BindableObject obj, Color value);
  public static void SetShellForegroundColor(BindableObject obj, Color value);
  public static void SetShellTabBarBackgroundColor(BindableObject obj, Color value);
  public static void SetShellTabBarDisabledColor(BindableObject obj, Color value);
  public static void SetShellTabBarForegroundColor(BindableObject obj, Color value);
  public static void SetShellTabBarTitleColor(BindableObject obj, Color value);
  public static void SetShellTabBarUnselectedColor(BindableObject obj, Color value);
  public static void SetShellTitleColor(BindableObject obj, Color value);
  public static void SetShellUnselectedColor(BindableObject obj, Color value);

  // Bindable Properties
  public static readonly BindableProperty CurrentItemProperty;
  public static readonly BindableProperty CurrentStateProperty;
  public static readonly BindableProperty FlyoutBackgroundColorProperty;
  public static readonly BindableProperty FlyoutHeaderBehaviorProperty;
  public static readonly BindableProperty FlyoutHeaderProperty;
  public static readonly BindableProperty FlyoutHeaderTemplateProperty;
  public static readonly BindableProperty FlyoutIsPresentedProperty;
  public static readonly BindableProperty GroupHeaderTemplateProperty;
  public static readonly BindableProperty ItemsProperty;
  public static readonly BindableProperty ItemTemplateProperty;
  public static readonly BindableProperty MenuItemsProperty;
  public static readonly BindableProperty MenuItemTemplateProperty;

  public Shell();

  public event EventHandler<ShellNavigatedEventArgs> Navigated;

  public event EventHandler<ShellNavigatingEventArgs> Navigating;

  public ShellItem CurrentItem {get; set;}

  public ShellNavigationState CurrentState {get; }

  public Color FlyoutBackgroundColor {get; set;}

  public FlyoutBehavior FlyoutBehavior {get; set;}

  public object FlyoutHeader {get; set;}

  public FlyoutHeaderBehavior FlyoutHeaderBehavior {get; set;}

  public DataTemplate FlyoutHeaderTemplate {get; set;}

  public bool FlyoutIsPresented {get; set;}

  public DataTemplate GroupHeaderTemplate {get; set;}

  public ShellItemCollection Items {get; }

  public DataTemplate ItemTemplate {get; set;}

  public MenuItemCollection MenuItems {get; }

  public DataTemplate MenuItemTemplate {get; set;}

  public string Route {get; set;}

  public string RouteHost { get; set; }

  public string RouteScheme { get; set; }

  public async Task GoToAsync(ShellNavigationState state, bool animate = true);

  protected virtual void OnNavigated(ShellNavigatedEventArgs args);

  protected virtual void OnNavigating(ShellNavigatingEventArgs args);
}

Descripción

Propiedades adjuntas:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| SearchHandlerProperty | Propiedad adjunta para la definición de una capacidad de búsqueda a nivel de página. Puede adjuntarse en varios puntos de la jerarquía. Utiliza algunas de las funciones definidas aquí https://material.io/guidelines/patterns/search.html#search -in-app-search |
| BackButtonBehavior | Permite anular completamente cómo se comporta el botón de retroceso. Se aplica a los botones de retroceso físicos y en pantalla. |
| FlyoutBehavior | Define cómo debe presentarse el Flyout. Esto se puede adjuntar a ShellItem s, ShellContent s o Page s para anular el comportamiento predeterminado. |
| NavBarVisibleProperty | Propiedad establecida en Page para definir si NavBar debe ser visible cuando se presenta |
| SetPaddingInsetsProperty | Establecer esta propiedad en un Page hará que su Padding se establezca de manera que su contenido no fluya bajo ningún Chrome de Shell. |
| TabBarVisibleProperty | Propiedad establecida en Page para definir si TabBar debe estar visible cuando se presenta |
| TitleViewProperty | Propiedad establecida en un Page para definir el TitleView |
| ShellBackgroundColorProperty | Describe el color de fondo que se debe utilizar para los elementos cromados del Shell. Este color no se completará detrás del Contenido del Shell. |
| ShellDisabledColorProperty | El color para sombrear el texto / los iconos que están desactivados |
| ShellForegroundColorProperty | El color para sombrear el texto / iconos normales en el shell |
| ShellTabBarBackgroundColorProperty | Reemplazo de ShellBackgroudnColor para TabBar. Si no se establece, se utilizará ShellBackgroundColor |
| ShellTabBarDisabledColorProperty | Reemplazo de ShellDisabledColor para TabBar. Si no se establece, se utilizará ShellDisabledColorProperty |
| ShellTabBarForegroundColorProperty | Reemplazo de ShellForegroundColorProperty para TabBar. Si no se establece, se utilizará ShellForegroundColorProperty |
| ShellTabBarTitleColorProperty | Reemplazo de ShellTitleColorProperty para TabBar. Si no se establece, se utilizará ShellTitleColorProperty |
| ShellTabBarUnselectedColorProperty | Reemplazo de ShellUnselectedColorProperty para TabBar. Si no se establece, se utilizará ShellUnselectedColorProperty |
| ShellTitleColorProperty | El color utilizado para el título de la página actual |
| ShellUnselectedColorProperty | El color utilizado para el texto / iconos no seleccionados en el shell chrome |

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| CurrentItem | El ShellItem seleccionado actualmente |
| CurrentState | El estado de navegación actual del Shell. Si vuelve a pasar este estado a GoToAsync, el Shell volverá a navegar hacia atrás. |
| FlyoutBackgroundColorProperty | El color de fondo del menú desplegable |
| FlyoutBehavior | Establece el FlyoutBehavior predeterminado para Shell . |
| FlyoutHeader | El objeto utilizado como encabezado del menú desplegable. Si FlyoutHeaderTemplate no es nulo, esto se pasa como BindingContext al objeto inflado. Si FlyoutHeaderTemplate es nulo y FlyoutHeader es del tipo View , se utilizará directamente. De lo contrario, se mostrará llamando a ToString () y mostrando el resultado. |
| FlyoutHeaderBehavior | Establece el comportamiento de FlyoutHeader cuando el Flyout necesita desplazarse para mostrar el contenido. |
| FlyoutHeaderTemplate | La plantilla utilizada para crear un encabezado para el Flyout. |
| FlyoutIsPresented | Obtiene o establece si el menú desplegable está visible en ese momento |
| GroupHeaderTemplate | El DataTemplate utilizado para mostrar un encabezado de grupo si un ShellItem solicita que se muestre como un grupo de pestañas en el menú desplegable. Si es nulo, no se muestra ningún encabezado. |
| Artículos | El contenido principal de un caparazón. Los elementos definen la lista de elementos que se mostrarán en el menú desplegable, así como el contenido que se mostrará cuando se seleccione un elemento de la barra lateral. |
| ItemTemplate | El DataTemplate utilizado para mostrar elementos de la colección Items en el menú desplegable. Permite al desarrollador controlar las imágenes en el menú desplegable. |
| MenuItems | Una colección de MenuItem s que aparecerán en el menú desplegable de su propia sección. |
| MenuItemTemplate | El DataTemplate que se usará cuando se muestre un MenuItem en el menú desplegable. |
| Ruta | La parte de la ruta para abordar este elemento al realizar enlaces profundos. |
| RouteHost | La cadena que se colocará en la parte del host del URI generado al crear enlaces profundos |
| RouteScheme | La cadena que se colocará en la parte del esquema del URI generado al crear enlaces profundos |

Métodos públicos:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| GoToAsync | Navegue hasta ShellNavigationState . Devuelve una tarea que se completará una vez que se haya completado la animación. |

Eventos publicos:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Navegando | El Shell está a punto de realizar una navegación debido a la interacción del usuario o al desarrollador que llama a una API. El desarrollador puede cancelar la navegación aquí si es posible. |
| Navegado | El Shell ha completado un evento de navegación. |

ShellItemCollection

Una colección por ShellItem s

public sealed class ShellItemCollection : IEnumerable<ShellItem>, IList<ShellItem>

MenuItemCollection

Una colección por MenuItem s

public sealed class MenuItemCollection : IEnumerable<MenuItem>, IList<MenuItem>

ShellSectionCollection

Una colección por ShellSection s

public sealed class ShellSectionCollection : IEnumerable<ShellSection>, IList<ShellSection>

ShellContentCollection

Una colección por ShellContent s

public sealed class ShellContentCollection : IEnumerable<ShellContent>, IList<ShellContent>

ShellNavigatingEventArgs

Un EventArgs usado para describir un evento de navegación que está a punto de ocurrir. El ShellNavigationEventArgs también se puede usar para cancelar el evento de navegación si el desarrollador lo desea.

public class ShellNavigatingEventArgs : EventArgs
{
  public ShellNavigationState Current { get; }

  public ShellNavigationState Target { get; }

  public ShellNavigationSource Source { get; }

  public bool CanCancel { get; }

  public bool Cancel ();
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Actual | El NavigationState actual de Shell . Llamar a GoToAsync con este ShellNavigationState deshará efectivamente este evento de navegación. |
| Objetivo | El estado en el que estará Shell después de que se complete este evento de navegación. |
| Fuente | El tipo de navegación que se produjo para desencadenar este evento. Puede haber varias banderas establecidas. |
| CanCancel | Si el evento de navegación es cancelable o no. No todos los eventos se pueden cancelar. |

Métodos públicos:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Cancelar | Cancela el evento de navegación actual. Devuelve verdadero si la cancelación se realizó correctamente. |

ShellNavigatedEventArgs

public class ShellNavigatedEventArgs : EventArgs
{
  public ShellNavigationState Previous { get; }

  public ShellNavigationState Current { get; }

  public ShellNavigationSource Source { get; }
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Anterior | El NavigationState anterior del Shell . |
| Actual | El nuevo estado en el que se encuentra Shell cuando se completó este evento de navegación. |
| Fuente | El tipo de navegación que se produjo para desencadenar este evento. Puede haber varias banderas establecidas. |

ShellNavigationState

public class ShellNavigationState
{
  public Uri Location { get; set; }

  public ShellNavigationState ();
  public ShellNavigationState (string location);
  public ShellNavigationState (Uri uri);

  public static implicit operator ShellNavigationState (Uri uri);
  public static implicit operator ShellNavigationState (String value);
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Ubicacion | El Uri que describe el estado de navegación de Shell |

Constructores:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| (nulo) | Crea un nuevo ShellNavigationState con una ubicación nula |
| (Cadena) | Crea un nuevo ShellNavigationState con la ubicación establecida en el string |
| (Uri) | Crea un nuevo ShellNavigationState con la ubicación establecida en el Uri |

ShellNavigationSource

[Flags]
public enum ShellNavigationSource
{
  Unknown = 0,
  Push,
  Pop,
  PopToRoot,
  Insert,
  Remove,
  ShellItemChanged,
  ShellSectionChanged,
  ShellContentChanged,
}

BaseShellItem

public class BaseShellItem : NavigableElement
{
  public static readonly BindableProperty FlyoutIconProperty;
  public static readonly BindableProperty IconProperty;
  public static readonly BindableProperty IsCheckedProperty;
  public static readonly BindableProperty IsEnabledProperty;
  public static readonly BindableProperty TitleProperty;

  public ImageSource FlyoutIcon { get; set; }

  public ImageSource Icon { get; set; }

  public bool IsChecked { get; }

  public bool IsEnabled { get; set; }

  public string Route { get; set; }

  public string Title { get; set; }
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| FlyoutIcon | El icono predeterminado que se utilizará cuando se muestre en el menú desplegable. Se establecerá de forma predeterminada en el icono si no se establece. |
| Icono | El icono que se muestra en partes del cromo que no son el Flyout. |
| IsChecked | Si el BaseShellItem está actualmente marcado en el menú desplegable (y por lo tanto debe estar resaltado) |
| IsEnabled | Si el BaseShellItem se puede seleccionar en el chrome |
| Ruta | Equivalente a configurar Routing.Route |
| Título | El título que se mostrará en la interfaz de usuario |

ShellGroupItem

public class ShellGroupItem : BaseShellItem
{
  public static readonly BindableProperty FlyoutDisplayOptionsProperty;;

  public FlyoutDisplayOptions FlyoutDisplayOptions { get; set; }
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| FlyoutDisplayOptions | Controla cómo se muestran este elemento y sus elementos secundarios en el menú desplegable |

ShellItem

[ContentProperty("Items")]
public class ShellItem : ShellGroupItem, IShellItemController, IElementConfiguration<ShellItem>
{
  public static readonly BindableProperty CurrentItemProperty;

  public ShellItem();

  public ShellSection CurrentItem { get; set; }

  public ShellSectionCollection Items;

  public static implicit operator ShellItem(ShellSection shellSection);

  public static implicit operator ShellItem(ShellContent shellContent);

  public static implicit operator ShellItem(TemplatedPage page);

  public static implicit operator ShellItem(MenuItem menuItem);
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| CurrentItem | El ShellSection . |
| Artículos | ShellSectionCollection que es el contenido principal de un ShellItem. Esta colección define todas las pestañas dentro de un ShellItem. |

ShellSection

[ContentProperty("Items")]
public class ShellSection : ShellGroupItem, IShellSectionController
{
  public static readonly BindableProperty CurrentItemProperty;
  public static readonly BindableProperty ItemsProperty

  public ShellSection();

  public ShellContent CurrentItem { get; set; }

  public ShellContentCollection Items { get; }

  public IReadOnlyList<Page> Stack { get; }

  public static implicit operator ShellSection(ShellContent shellContent);

  public virtual async Task GoToAsync(List<string> routes, IDictionary<string, string> queryData, bool animate);

  protected virtual IReadOnlyList<Page> GetNavigationStack();

  protected virtual void OnInsertPageBefore(Page page, Page before);

  protected async virtual Task<Page> OnPopAsync(bool animated);

  protected virtual async Task OnPopToRootAsync(bool animated);

  protected virtual Task OnPushAsync(Page page, bool animated);

  protected virtual void OnRemovePage(Page page);
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| CurrentItem | El ShellContent de ShellSection. |
| Artículos | El ShellContentCollection que es el contenido raíz de ShellSection. |
| Pila | La pila de navegación insertada actual en ShellSection. |

Métodos:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| GoToAsync | Utilizado por enlaces profundos para navegar a una ubicación conocida. No debería ser necesario llamar directamente en la mayoría de los casos. |
| GetNavigationStack | Devuelve la pila de navegación actual |
| OnInsertPageBefore | Se llama cuando se llama al método INavigation interfaces InsertPageBefore |
| OnPopAsync | Se llama cuando se llama al método INavigation interfaces PopAsync |
| OnPopToRootAsync | Se llama cuando se llama al método INavigation interfaces PopToRootAsync |
| OnPushAsync | Se llama cuando se llama al método INavigation interfaces PushAsync |
| OnRemovePage | Se llama cuando se llama al método INavigation interfaces RemovePage |

ShellContent

[ContentProperty("Content")]
public class ShellContent : BaseShellItem, IShellContentController
{
  public static readonly BindableProperty ContentProperty;
  public static readonly BindableProperty ContentTemplateProperty;
  public static readonly BindableProperty MenuItemsProperty;

  public ShellContent();

  public object Content { get; set; }

  public DataTemplate ContentTemplate { get; set; }

  public MenuItemCollection MenuItems { get; }

  public static implicit operator ShellContent(TemplatedPage page);
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Contenido | El contenido de un ShellContent. Por lo general, un ContentPage o el BindingContext del Page inflado por el ContentTemplate |
| ContentTemplate | Se utiliza para inflar dinámicamente el contenido de ShellContent . La propiedad Content se establecerá como BindingContext después de la inflación. |
| MenuItems | Los elementos que se mostrarán en el menú desplegable cuando este ShellContent es la página presentada |

SearchHandler

public class SearchHandler : BindableObject, ISearchHandlerController
{
  public static readonly BindableProperty ClearIconHelpTextProperty;
  public static readonly BindableProperty ClearIconNameProperty;
  public static readonly BindableProperty ClearIconProperty;
  public static readonly BindableProperty ClearPlaceholderCommandParameterProperty;
  public static readonly BindableProperty ClearPlaceholderCommandProperty;
  public static readonly BindableProperty ClearPlaceholderEnabledProperty;
  public static readonly BindableProperty ClearPlaceholderHelpTextProperty;
  public static readonly BindableProperty ClearPlaceholderIconProperty;
  public static readonly BindableProperty ClearPlaceholderNameProperty;
  public static readonly BindableProperty CommandParameterProperty;
  public static readonly BindableProperty CommandProperty;
  public static readonly BindableProperty DisplayMemberNameProperty;
  public static readonly BindableProperty IsSearchEnabledProperty;
  public static readonly BindableProperty ItemsSourceProperty;
  public static readonly BindableProperty ItemTemplateProperty;
  public static readonly BindableProperty PlaceholderProperty;
  public static readonly BindableProperty QueryIconHelpTextProperty;
  public static readonly BindableProperty QueryIconNameProperty;
  public static readonly BindableProperty QueryIconProperty;
  public static readonly BindableProperty QueryProperty;
  public static readonly BindableProperty SearchBoxVisibilityProperty;
  public static readonly BindableProperty ShowsResultsProperty;

  public ImageSource ClearIcon { get; set; }

  public string ClearIconHelpText { get; set; }

  public string ClearIconName { get; set; }

  public ICommand ClearPlaceholderCommand { get; set; }

  public object ClearPlaceholderCommandParameter { get; set; }

  public bool ClearPlaceholderEnabled { get; set; }

  public string ClearPlaceholderHelpText { get; set; }

  public ImageSource ClearPlaceholderIcon { get; set; }

  public string ClearPlaceholderName { get; set; }

  public ICommand Command { get; set; }

  public object CommandParameter { get; set; }

  public string DisplayMemberName { get; set; }

  public bool IsSearchEnabled { get; set; }

  public IEnumerable ItemsSource { get; set; }

  public DataTemplate ItemTemplate { get; set; }

  public string Placeholder { get; set; }

  public string Query { get; set; }

  public ImageSource QueryIcon { get; set; }

  public string QueryIconHelpText { get; set; }

  public string QueryIconName { get; set; }

  public SearchBoxVisiblity SearchBoxVisibility { get; set; }

  public bool ShowsResults { get; set; }

  protected virtual void OnClearPlaceholderClicked();

  protected virtual void OnItemSelected(object item);

  protected virtual void OnQueryChanged(string oldValue, string newValue);

  protected virtual void OnQueryConfirmed();
}

Propiedades:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| ClearIconHelpText | El texto de ayuda accesible para el icono claro |
| ClearIconNameProperty | El nombre del icono transparente para usar con lectores de pantalla |
| ClearIcon | El icono que se muestra para borrar el contenido del cuadro de búsqueda. |
| ClearPlaceholderCommandParameter | El parámetro para ClearPlaceholderCommand |
| ClearPlacehodlerCommand | El comando que se ejecutará cuando se toque el icono de ClearPlaceholder |
| ClearPlaceholderEnabled | El estado habilitado de ClearPlaceholderIcon. El valor predeterminado es verdadero. |
| ClearPlaceholderHelpText | El texto de ayuda accesible para el icono de marcador de posición claro |
| ClearPlaceholderIcon | El icono que se muestra en la ubicación ClearIcon cuando el cuadro de búsqueda está vacío. |
| ClearPlaceholderName | El nombre del icono de marcador de posición transparente para su uso con lectores de pantalla |
| CommandParameter | El parámetro para Command |
| Comando | El ICommand para ejecutar cuando se confirma una consulta
| DisplayMemberPath | El nombre o la ruta de la propiedad que se muestra para cada elemento de datos en ItemsSource . |
| IsSearchEnabled | Controla el estado habilitado del cuadro de búsqueda. |
| ItemsSource | Una colección de elementos para mostrar en el área de sugerencias. |
| ItemTemplate | Una plantilla para los elementos que se muestran en el área de sugerencias. |
| Marcador de posición | Una cadena que se muestra cuando el cuadro de búsqueda está vacío. |
| QueryIconHelpTextProperty | El texto de ayuda accesible para el icono de consulta |
| QueryIconNameProperty | El nombre del icono de consulta para su uso con lectores de pantalla |
| QueryIcon | El icono utilizado para indicar al usuario que la búsqueda está disponible |
| Consulta | La cadena actual en el cuadro de búsqueda. |
| SearchBoxVisibility | Define la visibilidad del cuadro de búsqueda en el cromo Shell s. |
| ShowsResults | Determina si se deben esperar resultados de búsqueda al ingresar texto |

Métodos protegidos:

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| OnClearPlaceholderClicked | Se llama cada vez que se presiona el icono ClearPlaceholder. |
| OnItemSelected | Llamado cada vez que el usuario presiona un resultado de búsqueda |
| OnQueryConfirmed | Se llama cada vez que el usuario presiona enter o confirma su entrada en el cuadro de búsqueda. |
| OnQueryChanged | Se llama cuando se cambia Query . |

SearchBoxVisiblity

public enum SearchBoxVisiblity
{
  Hidden,
  Collapsable,
  Expanded
}

| Valor | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Oculto | El cuadro de búsqueda no es visible ni accesible. |
| Plegable | El cuadro de búsqueda está oculto hasta que el usuario realiza una acción para revelarlo. |
| Ampliado | El cuadro de búsqueda es visible como una entrada completamente expandida. |

AtrásBotónComportamiento

public class BackButtonBehavior : BindableObject
{
  public ImageSource IconOverride { get; set; }
  public string TextOverride { get; set; }
  public ICommand Command { get; set; }
  public object CommandParameter { get; set; }
}

| API | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| IconOverride | Cambia el icono utilizado para el botón de retroceso. |
| TextOverride | Cambia el texto utilizado para indicar la navegación hacia atrás si se utiliza texto. |
| Comando | Proporciona un comando de reemplazo para invocar cuando se presiona el botón Atrás. |
| CommandParameter | El parámetro de comando usado con Command |

FlyoutDisplayOptions

Determina cómo se debe mostrar ShellGroupItem en el menú desplegable.

  public enum FlyoutDisplayOptions
  {
    AsSingleItem,
    AsMultipleItems,
  }

| Valor | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| AsSingleItem | El ShellGroupItem será visible como una sola entrada en el menú desplegable. |
| AsMultipleItems | El ShellGroupItem será visible como un grupo de elementos, uno para cada niño en el menú desplegable. |

FlyoutHeaderBehavior

Controla el comportamiento del FlyoutHeader al desplazarse.

public enum FlyoutHeaderBehavior {
  Default,
  Fixed,
  Scroll,
  CollapseOnScroll,
}

| Valor | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Por defecto | Comportamiento predeterminado de la plataforma. |
| Fijo | El encabezado permanece visible y sin cambios en todo momento |
| Desplazarse | El encabezado se desplaza fuera de la vista cuando el usuario se desplaza por el menú |
| CollapseOnScroll | El encabezado se contrae al título solo cuando el usuario se desplaza |

FlyoutBehavior

public enum FlyoutBehavior
{
  Disabled,
  Flyout,
  Locked
}

| Valor | Descripción |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Discapacitados | El usuario no puede acceder al menú desplegable. |
| Flyout | El menú desplegable funciona como un control flotante normal que el usuario puede abrir / cerrar. |
| Bloqueado | El Flyout está bloqueado y el usuario no puede cerrarlo, no sobrepasa el contenido. |

DataTemplateExtension

Esta extensión convierte rápidamente un tipo en una ControlTemplate. Esto es útil para los casos en los que la plantilla se especificaría como

<ListView>
  <ListView.ItemTemplate>
    <DataTemplate>
      <local:MyCell />
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

Esto luego se puede condensar en

<ListView ItemTemplate="{DataTemplate local:MyCell}" />
public sealed class ControlTemplateExtension : IBindingExtension<ControlTemplate>
public sealed class DataTemplateExtension : IBindingExtension<DataTemplate>

Retazos

¿Qué sucede cuando selecciona una pestaña en Flyout que se ha empujado a?

Esto es el equivalente a enfocar la pestaña y llamar a PopToRoot en ella.

¿Qué sucede cuando cambio ShellItems y hay elementos en el backstack de un ShellContent del antiguo ShellItem?

Si el ShellItem antiguo tiene una plantilla, la pila de actividades se pierde. Si el ShellItem no tiene plantilla, el BackStack permanece intacto y cuando se cambia de nuevo al antiguo ShellItem, el backstack se reflejará correctamente. Sin embargo, volver a cambiar puede despejar el backstack, como se indica en la respuesta anterior.

Carga eficaz de páginas

Un problema importante con el uso de Shell es la facilidad con la que un usuario puede terminar cargando todas las páginas al inicio de la ejecución de su aplicación. Esta gran asignación de carga anticipada puede resultar en un rendimiento de inicio bastante pobre si se necesita una gran cantidad de páginas de contenido. Para solucionar este problema, se deben emplear plantillas siempre que sea posible.

Contenido de Shell con plantilla

La creación de plantillas de elementos de la pestaña de shell es la forma más granular de creación de plantillas disponible; afortunadamente, también es la más fácil de hacer. Toma el siguiente caparazón.

<?xml version="1.0" encoding="utf-8" ?>
<MaterialShell xmlns="http://xamarin.com/schemas/2014/forms"
               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
               xmlns:local="clr-namespace:MyStore"
               x:Class="MyStore.Shell">

  <ShellItem Title="My apps &amp; games">
    <local:UpdatesPage />
    <local:InstalledPage />
    <local:LibraryPage />
  </ShellItem>

  <ShellItem GroupBehavior="ShowTabs">
    <local:HomePage />
    <local:GamesPage />
    <local:MoviesTVPage />
    <local:BooksPage />
    <local:MusicPage />
    <local:NewsstandPage />
  </ShellItem>
</MaterialShell>

Cuando se cargue este Shell, las 9 páginas se inflarán a la vez. Esto se debe a que no se emplean plantillas. Para emplear plantillas básicas, podemos convertir esto en:

<?xml version="1.0" encoding="utf-8" ?>
<MaterialShell xmlns="http://xamarin.com/schemas/2014/forms"
               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
               xmlns:local="clr-namespace:MyStore"
               x:Class="MyStore.Shell">

  <ShellItem Title="My apps &amp; games">
    <ShellContent Title="Updates"        Icon="updates.png" ContentTemplate="{DataTemplate local:UpdatesPage}" />
    <ShellContent Title="Installed Apps" Icon="apps.png"    ContentTemplate="{DataTemplate local:InstalledPage}" />
    <ShellContent Title="Library"        Icon="library.png" ContentTemplate="{DataTemplate local:LibraryPage}" />
  </ShellItem>

  <ShellItem GroupBehavior="ShowTabs">
    <ShellContent Title="Home"          Icon="updates.png"   ContentTemplate="{DataTemplate local:HomePage}" />
    <ShellContent Title="Games"         Icon="games.png"     ContentTemplate="{DataTemplate local:GamesPage}" />
    <ShellContent Title="Movies and TV" Icon="moviesTV.png"  ContentTemplate="{DataTemplate local:MoviesTVPage}" />
    <ShellContent Title="Books"         Icon="books.png"     ContentTemplate="{DataTemplate local:BooksPage}" />
    <ShellContent Title="Music"         Icon="music.png"     ContentTemplate="{DataTemplate local:MusicPage}" />
    <ShellContent Title="Newsstand"     Icon="newsstand.png" ContentTemplate="{DataTemplate local:NewsstandPage}" />
  </ShellItem>
</MaterialShell>

Las páginas ahora solo se cargan según sea necesario y también se pueden descargar según sea necesario. Si es necesario, los propios ShellItem también se pueden crear plantillas con una colección y un DataTemplateSelector que evita que incluso los ShellContents tengan que cargarse con entusiasmo, sin embargo, esto es en gran parte innecesario y la plantilla ShellItem es más útil para Shells que tienen ShellItems con un gran número de pestañas similares. . La creación de plantillas de ShellContent debería ser el área clave para proporcionar plantillas para problemas de rendimiento.

Reconstrucción de la interfaz de usuario de Google Play Store

Tenga en cuenta que esto no pretende ser una demostración de la mejor manera de codificar una aplicación, sino el formato más conciso para combinar la interfaz de usuario para GPS. Tampoco intenta virtualizar las páginas relevantes utilizando ViewModels y DataTemplateSelector's. Esto significa que el rendimiento sería bastante malo, ya que todas las páginas se cargarían al inicio de la aplicación. Se advierte al lector.

Se supone que todo el contenido de la página funciona correctamente, esto es solo para tener una idea general de Chrome.

Shell.xaml

Una implementación adecuada de esto usaría ShellItems para cada página y establecería ItemsSource y ItemTemplate. Esto permitiría que cada página solo se cargue una vez que se necesite y que se descargue cuando ya no se necesite.

<?xml version="1.0" encoding="utf-8" ?>
<MaterialShell xmlns="http://xamarin.com/schemas/2014/forms"
               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
               xmlns:local="clr-namespace:MyStore"
               x:Class="MyStore.Shell"
               FlyoutHeaderBehavior="Fixed"
               FlyoutHeader="{x:Bind HeaderViewModel}">
  <MaterialShell.FlyoutHeaderTemplate>
    <local:CircleImageAndLabelControl HeightRequest="350" />
  </MaterialShell.FlyoutHeaderTempalte>

  <ShellItem Title="My apps &amp; games">
    <ShellItem.ShellAppearance>
      <MaterialShellAppearance NavBarCollapseStyle="Full">
    </ShellItem.ShellAppearance>
    <local:UpdatesPage />
    <local:InstalledPage />
    <local:LibraryPage />
  </ShellItem>

  <local:NotificationsPage Title="My notifications" />

  <local:SubscriptionsPage />

  <ShellItem GroupBehavior="ShowTabs">
    <ShellItem.ShellAppearance>
      <MaterialShellAppearance NavBarCollapseStyle="Full" TabBarCollapseStyle="Full" UseSwipeGesture="false">
    </ShellItem.ShellAppearance>
    <local:HomePage />
    <local:GamesPage />
    <ShellContent Title="Movies &amp; TV" Icon="moviesTV.png" ContentTemplate="{DataTemplate local:MoviesTVPage}">
      <ShellContent.MenuItems>
        <MenuItem Title="Open Movies &amp; TV app" Command="{xBind MoviesTVAppCommand}" />
      </ShellContent.MenuItems>
    </ShellContent>
    <ShellContent Title="Books" Icon="books.png" ContentTemplate="{DataTemplate local:BooksPage}">
      <ShellContent.MenuItems>
        <MenuItem Title="Open Books app" Command="{xBind BooksAppCommand}" />
      </ShellContent.MenuItems>
    </ShellContent>
    <ShellContent Title="Music" Icon="music.png" ContentTemplate="{DataTemplate local:MusicPage}">
      <ShellContent.MenuItems>
        <MenuItem Title="Open Music app" Command="{xBind MusicAppCommand}" />
      </ShellContent.MenuItems>
    </ShellContent>
    <ShellContent Title="Newsstand" Icon="newsstand.png" ContentTemplate="{DataTemplate local:NewsstandPage}">
      <ShellContent.MenuItems>
        <MenuItem Title="Open Newsstand app" Command="{xBind NewsstandAppCommand}" />
      </ShellContent.MenuItems>
  </ShellItem>

  <local:AccountPage />

  <MenuItem Title="Redeem" Icon="redeem.png" Command="{x:Bind RedeemCommand}" />

  <local:WishlistPage />

  <MenuItem Title="Play Protect" Icon="protect.png" Command="{x:Bind NavigateCommand}" CommandParameter="ProtectPage" />

  <MenuItem Title="Settings" Icon="settings.png" Command="{x:Bind SettingsCommand}" CommandParameter="SettingsPage" />

  <MaterialShell.MenuItems>
    <MenuItem Title="Help &amp; feedback" Command="{x:Bind NavigateCommand}" CommandParameter="HelpPage" />
    <MenuItem Title="Parent Guide" Command="{x:Bind NavigateCommand}" CommandParameter="ParentPage" />
    <MenuItem Title="Help &amp; feedback" Command="{x:Bind UrlCommand}" CommandParameter="http://support.google.com/whatever" />
  </MaterialShell.MenuItems>
</MaterialShell>

Las páginas de la tienda

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyStore"
             x:Class="MyStore.HomePage"
             Title="Home"
             Icon="home.png"
             ShellAppearance.BackgroundColor="Green">
  <Label Text="Home content here" />
</ContentPage>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyStore"
             x:Class="MyStore.MoviesTVPage"
             Title="Movies &amp; TV"
             Icon="movies.png"
             ShellAppearance.BackgroundColor="Red">
  <Label Text="Movies and TV content here" />
</ContentPage>

Y para agregar la barra de búsqueda.

public class HomePage : ContentPage
{
  public class HomeSearchHandler : SearchHandler
  {
    public HomeSearchHandler ()
    {
      SearchBoxVisibility = SearchBoxVisibility.Expanded;
      IsSearchEnabled = true;
      Placeholder = "Google Play";
      CancelPlaceholderIcon = "microphone.png"
    }

    protected override void OnSearchConfirmed (string query)

{      // Navigate to search results page here
    }

    protected override void OnSearchChanged (string oldValue, string newValue)
    {
    }

    protected override void OnCancelPlaceholderPressed ()
    {
      // Trigger voice API here
    }
  }

  public HomePage
  {
    Shell.SetSearchHandler (this, new HomeSearchHandler ());
  }  
}

Y así sucesivamente configurando los colores y el contenido correctamente.

Para páginas como la página de Configuración, donde el menú lateral no debería ser accesible hasta que se presione el botón Atrás:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyStore"
             x:Class="MyStore.SettingsPage"
             Title="Settings"
             Icon="settings.png"
             ShellAppearance.BackgroundColor="Grey"
             MaterialShell.FlyoutBehavior="Disabled">
  <Label Text="Settings content here" />
</ContentPage>

HACER

  • [x] Agregar API para el cuadro de búsqueda
  • [x] Agregar API para el manejo de ContentSafeArea
  • [x] Agregar API para menú flotante
  • [x] Agregar API para los elementos del menú de la ventana
  • [x] Agregar API para snackbar
  • [x] Agregar API para interrumpir la navegación
  • [x] Agregar API para la hoja inferior
  • [x] Agregar API para posicionar FAB
  • [x] Agregue historias para que las ideas de navegación sean más claras (parcialmente hecho)
  • [x] Agregar API de estilo LeftBarButton
  • [x] Agregar mecanismo para obtener Back Stack de ShellContent
  • [x] Agregar API para cambiar el color de la cinta según la pestaña seleccionada
  • [x] Agregar soporte de sugerencias opcional para SearchHandler
  • [x] Agregue soporte para configurar la barra de búsqueda siempre expandida frente a la barra de búsqueda como ícono
  • [x] Agregue API para obtener la página "Actual" de la clase MaterialShell. Necesario para algunos escenarios de navegación.
  • [x] Agregar API para guardar "estados" en la pila de actividades
  • [x] Agrega API para evitar que salga el flyout
  • [x] Agregue API para elementos de "submenú" para el GPS ala de ShellContent -> Música -> Aplicación de música abierta
  • [x] Agregar API para el comando y el ícono Cancelar marcador de posición (generalmente se usa para el ícono de micrófono para la búsqueda por voz)
  • [x] API de Segue
  • [x] Descubra qué hacer con INavigation
  • [] Expanda la API de la hoja inferior para que coincida con las capacidades de Google Maps
  • [x] API para manejar la presentación de Flyout
  • [] API para deshabilitar el gesto de Flyout cuando sea necesario
  • [] API de título grande
  • [] API de transiciones

Cuestiones

ISearchHandler [CORREGIDO]

Hay muchas cosas que esta interfaz está haciendo y, lo que es peor, probablemente tendrá que expandirse a medida que pase el tiempo. Por lo tanto, es lógico pensar que probablemente debería ser una clase base abstracta que el usuario pueda implementar. Este desafortunado significa otra asignación de objetos. Sin embargo, mantiene la flexibilidad en el futuro. Es probable que se produzca este cambio.

Menú flotante

La API de adjuntos es un poco pesada y quizás demasiado confusa para los usuarios. Peor aún, es posible que no se asigne muy bien a todas las plataformas para asegurarse de que el archivo adjunto funcione con animaciones. Se requiere más trabajo para validar esta API.

shell enhancement ➕

Comentario más útil

Amigos, ayer Jason y yo tuvimos una discusión sobre cómo mejorar esta especificación y haremos una gran actualización, lo dividiremos en diferentes temas.

Todos 199 comentarios

¡Hagamos que esta conversación se convierta en un zumbido, porque realmente necesitamos saber de usted, nuestra comunidad de desarrolladores!

PRIMERO, gracias @jassmith por trabajar para capturar esto y elaborar una propuesta para que la discutamos abiertamente aquí.

Voy a compartir algunos de mis pensamientos, hacer algunas preguntas estúpidas y, con suerte, algunas preguntas no demasiado importantes. Como Administrador de programas de Xamarin.Forms, a menudo tengo que hacer preguntas de tal manera que parezca que no tengo ni idea (a veces no), pero en realidad solo necesito escuchar cosas de USTED sin poniendo palabras en tu boca.

Hay cosas que me gustan en esta propuesta, porque puedo ver cómo podrían abordar algunos de los problemas de los que he estado hablando con muchos, muchos de ustedes, y estamos trabajando para resolverlos.

También tengo reservas.

Comenzaré aquí con un par de discusiones generales sobre el concepto de Shell y la experiencia del desarrollador.

Experiencia de la aplicación

para obtener una experiencia de aplicación completa que esté correctamente estructurada, use los elementos correctos, con muy poco esfuerzo y un camino claro para ser bueno por defecto.

Si utilizo este enfoque para describir mi aplicación en el nivel superior, obtengo:

  • una aplicación con el mismo tema en todas las plataformas
  • Patrones de diseño de material (en este caso) activados por defecto
  • los últimos patrones de navegación habilitados con la configuración
  • ¿No tengo que trabajar para personalizar Entry o Button para que tengan el mismo aspecto en iOS, Android y UWP?

¿Es eso exacto? ¿Otros beneficios que debo destacar?

En lugar de App tengo MaterialShell . ¿Necesito aprender / adoptar un nuevo paradigma de aplicación de nivel superior para beneficiarme de esto?

Una vez que estoy en mi aplicación, estoy de vuelta en ContentPage land, ¿correcto? Pero todos mis Button sy Entry s están materializados y son bonitos. ¿Puedo todavía OnPlatform y similares cambiar la apariencia (o comportamiento) para ser diferente en otra plataforma?

¿Cómo se ve mi ruta de migración desde una aplicación existente hasta el uso de este "shell"? Presento el nuevo MaterialShell , describo cómo quiero que mi aplicación sea la estructura y el aspecto, y simplemente la ejecuto para ver la nueva bondad.

Personalización

¿Cuáles son mis opciones si me gusta la apariencia de Flyout o los elementos del menú, pero necesito modificarlos para que coincidan con las composiciones de mis diseñadores? ¿En qué momento estoy diciendo "Uf, debería haber rodado todo esto yo mismo" y moviendo lo que tengo a una estructura de aplicación estándar de Xamarin.Forms?

Si tengo que abandonar totalmente el MaterialShell , ¿pierdo toda esa bondad de estilo y vuelvo a donde comencé (como hoy) con un Entry ve bastante diferente entre iOS y Android y UWP? ? Me gustaría no hacerlo.

Hay un punto de inflexión que estoy anticipando. Después de haber usado este enfoque para ponerme en marcha rápidamente, llegaré a algunas limitaciones y necesitaré explorar mis opciones. ¿Qué son y en qué momento es mejor no usar MaterialShell ?

El problema

Cerraré este primer comentario con algunas preguntas para todos los que lean.

  • ¿Está bien definido el problema que esta propuesta intenta abordar?
  • ¿Es un problema que compartes?
  • Al leer esta especificación, ¿qué problemas a los que se ha enfrentado en proyectos anteriores cree que esto le resolvería?

Si es posible, las capturas de pantalla / imágenes de diseño mejorarían aún más.

También mira esto:

http://www.noesisengine.com/webgl/Samples.Buttons.html

@jassmith Hubiera sido genial si toda la idea se presentara como imágenes. Felicitaciones por el esfuerzo de presentar las especificaciones. Puede que mis preguntas no sean correctas.

Mis consultas son

  • Compatibilidad con tabletas, no se aborda la capacidad de respuesta de la aplicación que se adapta a diferentes diseños.
  • ¿Será un desafío la migración del modelo actual al nuevo modelo? Desde la perspectiva del desarrollador de aplicaciones y la perspectiva de los colaboradores de Xamarin Forms.
  • Estoy de acuerdo en que la mayoría de la aplicación necesita una sola interfaz de usuario (debido a la cantidad de renderizadores personalizados que tenemos que escribir en algún momento para lograr los mismos conceptos de interfaz de usuario) sin respetar las especificaciones de la plataforma, ¿la nueva dirección eliminará todas las características existentes, como si todavía desarrollamos Xamarin.Forms? aplicaciones con interfaz de usuario específica de la plataforma, o todos se verán obligados a cumplir con los nuevos estándares.
  • ¿Los conceptos de renderizador seguirán existiendo dentro de MaterialShell?
  • ¿Podemos realmente decir, en iOS, que queremos que esto se renderice de esta manera? Flutter tiene Cupertino Styles (interfaz de usuario de Apple) que funciona en Android y la interfaz de usuario de Android que funciona en iOS. ¿En qué dirección se moverá Xamarin Forms? ¿El desarrollador tendrá ese tipo de capacidades que ofrece flutter ahora?

¿Esto también incluirá algo similar al TextInputLayout para admitir etiquetas flotantes / marcadores de posición, así como mensajes de error? En caso afirmativo, creo que Binding debería extenderse para incluir 'ValidateOnDataErrors` similar a wpf.

Mira mi implementación de esto aquí
https://github.com/XamFormsExtended/Xfx.Controls/blob/develop/src/Xfx.Controls/XfxBinding.cs

Además, me pregunto si MaterialShell debería extender Shell para que uno pueda crear un HumanInterfaceShell para la apariencia de iOS.

@ChaseFlorell ese iba a ser mi comentario también. El material es genial, pero es otra cosa si queremos escribir nuestros propios shells para satisfacer las necesidades particulares de la interfaz de usuario.

@davidortinau , @jassmith ,

Gracias por recopilar esta especificación y permitirnos enviar comentarios.

¿Está bien definido el problema que esta propuesta intenta abordar?

Si. El sistema de navegación no está completamente desarrollado en Xamarin Forms, por lo que existe un problema abierto sobre cómo completarlo o evitarlo por completo.

¿Es un problema que compartes?

Si.

Al leer esta especificación, ¿qué problemas a los que se ha enfrentado en proyectos anteriores cree que esto le resolvería?

Voy a responder con esta pregunta diciendo que no creo que vaya a resolver problemas. Nuestros problemas particulares son que el sistema de navegación actual es demasiado rígido, no que no sea lo suficientemente rígido. El ejemplo más claro para nosotros es TabbedPage. No hay vista TabbedView, por lo que si queremos pestañas en nuestra aplicación, debemos usar TabbedPage. Por lo tanto, toda la pantalla debe estar ocupada por TabbedPage y no podemos usar espacio para botones propios u otros controles que queramos poner en la pantalla. Mi recomendación hubiera sido mover más funcionalidad _ fuera de_ Pages y bajar a Vistas en lugar de mover la funcionalidad en Pages a una capa superior una vez más.

Cosas como FloatingMenu y FlyoutBehavior me asustan porque implican que la navegación estará más codificada en el sistema Xamarin.Forms y se quitará más control a los desarrolladores de software. Puedo ver algún valor en tener un enfoque más estandarizado, pero definitivamente tendrá un costo.

Siempre hemos trabajado en otras tecnologías basadas en XAML como Silverlight, WPF y UWP. En esas tecnologías, tenemos un enfoque mucho más abierto en el que podemos definir más cómo funciona la navegación. Recientemente, contratamos a un consultor de UI / UX. No estaba al tanto de las peculiaridades de XF. Solo le pedimos que nos construyera algunas pantallas basadas en la funcionalidad de nuestro software. Grandes franjas de lo que recomendó no se pudieron implementar debido a cosas como no tener un TabbedView. Me temo que en lugar de facilitar la navegación, lo que sucederá es que este marco realmente dificultará la implementación de los diseños que nos brindan los diseñadores de UX / UI.

La otra cosa que diría es que este marco parece sin precedentes en otras plataformas XAML, y diría que la prioridad debería ser proporcionar estandarización en todas las plataformas en lugar de proporcionar nuevos marcos con los que las otras plataformas no serán compatibles. Actualmente, estamos compilando para tres plataformas: Silverlight, Xamarin.Forms y WPF. Lo que necesitamos es la estandarización en esas plataformas para crear menos desviaciones, no más.

@dylanberry ,

es otra cosa si queremos escribir nuestros propios shells para satisfacer las necesidades particulares de la interfaz de usuario.

Si. Ésta es mi preocupación. Cada aplicación tiene sus propios casos de uso particulares, y es probable que una mayor rigidez haga que sea más difícil, no más fácil, implementarlos.

También existe esta preocupación: https://github.com/xamarin/Xamarin.Forms/issues/2452#issuecomment -380991817

Me haré eco de lo anterior, y también preguntaré cómo funcionarán los gestos y los punteros.

Un comentario general es que por cada línea de código que se agrega a un sistema, hay más de 3 posibilidades de que se agregue código con errores. Ya hay muchos errores en Xamarin Forms que deben corregirse. Más código significa que las posibilidades de que se agreguen errores aumentan exponencialmente. Habrá más errores. Creo que el equipo de XF debería trabajar para reducir el tamaño del código base en lugar de aumentarlo. Disminuir la base del código es la única forma de disminuir la probabilidad de que ocurran errores.

¿Por qué inventar algo nuevo de nuevo en lugar de corregir los errores existentes y primero asegurarse de que todo sea sólido como una roca?

Para mí, se ha mencionado, pero la navegación es el mayor obstáculo en Xamarin Forms y me ha causado más dolor en los últimos tres años.

La navegación no es consistente en las tres plataformas con el patrón MasterDetail que causa muchos problemas con la hamburguesa que lo obliga a enviar páginas modales, luego debe implementar una barra de navegación personalizada ya que no puede volver a agregar, pero la animación se ve horrible en Android (incluso en MD).

  • Idealmente, debería poder optar por no participar y anular el contenido de la barra de navegación con su propio ContentView en muchos casos. PlatformSpecifics se planteó originalmente como algo que habría permitido el posicionamiento de los elementos de la barra de herramientas (hace mucho tiempo cuando estaba hablando con Bryan) pero resultó ser algo de uso limitado.

  • Capacidad para anular cosas del marco como animaciones de páginas emergentes

Mucho de lo que se propone parece muy, muy útil, siempre que pueda usar material shell en páginas específicas y no sea para toda la aplicación, el código será realmente útil. Ciertamente es algo que usaríamos porque en la actualidad sigo diciendo "Es una limitación de Xamarin Forms" mucho a nuestro tipo de UX (como lo hice en mi puesto anterior). Me atrevo a decirlo, deberíamos obtener los comentarios desde una perspectiva de UX que hayan diseñado aplicaciones de Forms anteriormente. Debería ser opcional como XamlC.

Sin embargo, no estoy seguro del nombre, FlexShell tendría más sentido ... pero ahora tenemos Flexbox (aunque nunca lo pedimos ... lo siento David, no pude evitarlo 😄)

Además, ¿significaría esto que los temas están algo muertos? nunca los usé de todos modos.

@mackayn

Ciertamente es algo que usaríamos porque en la actualidad sigo diciendo "Es una limitación de Xamarin Forms" mucho a nuestro tipo de UX (como lo hice en mi puesto anterior).

Bien, pero, ¿no tendría más sentido corregir o mejorar la implementación actual en lugar de crear una completamente nueva, que también vendrá con errores y limitaciones? Dice ahí mismo que:

MaterialShell es una API obstinada en algunos puntos "

En serio, ¿en cuántas direcciones diferentes puede ir Xamarin Forms? El equipo de XF apenas puede seguir arreglando la implementación actual de XF para al menos Android e iOS, ¿y ahora esto? ¿Qué pasa con la corrección de errores, la corrección de la vista previa de XAML, y el rendimiento?

Hubo un ticket abierto por alguien con una propuesta para agregar un soporte simple pero muy útil para el pincel sólido y degradado multiplataforma, pero la respuesta de @jassmith fue que sería problemático. Pero ahora este boleto propone lo mismo ... ¿Cómo ya no es problemático? Imagínate

@opcodewriter

Sí, he estado diciendo que durante el último año, hay una rareza de navegación que frena al equipo de Prism, por ejemplo, y nunca han podido resolver los problemas.

Sin embargo, solo estoy tratando de ofrecer comentarios constructivos por ahora, Xamarin Forms se encuentra en una coyuntura crítica en su evolución, esta API podría abordar muchos de los puntos débiles si se implementa de una manera flexible y no como un enfoque general de la aplicación.

@jassmith, ¿esto significa que XF adoptará el enfoque de Flutter (usando un motor de renderizado en lugar de controles nativos) para el Shell?

Amigos, ayer Jason y yo tuvimos una discusión sobre cómo mejorar esta especificación y haremos una gran actualización, lo dividiremos en diferentes temas.

Me gustaría hacerme eco de algunos de los sentimientos anteriores: por favor, mejoremos lo que tenemos, a menos que, por supuesto, tenga recursos ilimitados, entonces adelante 😉

Todavía quedan muchas cosas: arreglar ListView (es difícil creer que esto todavía no funciona correctamente), implementar controles como CheckBox, RadioButton, implementar el soporte de pincel (SolidColorBrush, GradientBrush), capacidad para mostrar una ventana emergente basada en una página o ContentView, corrección de errores (consulte el error reciente informado sobre vistas transparentes), rendimiento, herramientas y mucho más ...

¿Por qué querrías empezar algo nuevo ?????

@TonyHenrique Sí, las fotos serían geniales. Desafortunadamente, no soy un artista y no tengo los derechos de las imágenes que estoy usando para mi propia referencia. Espero que algún miembro del equipo de diseño tenga tiempo para ayudarme a producir imágenes adecuadas para la especificación.

@muhaym

  • Soporte para tableta. Su objetivo es asegurarse de que el diseño se adapte a las tabletas. Esto no cubrirá los casos de diseño dentro de sus páginas de contenido, por supuesto, esa sería una característica diferente. En gran parte, manejaría eso con el nuevo VSM.
  • Principalmente, simplemente coloque sus ContentPages en el lugar correcto y se adapte a los nuevos conceptos de navegación. No diré que siempre será trivial, pero tampoco debería ser debilitante.
  • Absolutamente no eliminará ninguna característica. De hecho, estoy trabajando en la actualización de la especificación para incluir una clase base de Shell que pierde algunas de las características de MaterialShell, pero por lo demás es una versión de interfaz de usuario específica de la plataforma de Shell.
  • Si. Agregar un dibujo solo cambia el renderizador que obtiene a algo que sabe cómo manejar un dibujo.
  • Si. Puede intercambiar qué renderizador se usa en cualquier nivel de la jerarquía. Los renderizadores simplemente se cambian mediante la configuración de plantillas con claves especiales en los diccionarios de recursos. Puede cambiar estas plantillas a lo que desee o deshabilitarlas estableciendo un valor nulo para ellas.

@ChaseFlorell no, pero estoy abierto a sugerencias si desea adjuntar una enmienda a la especificación. En cuanto a lo de Shell vs MaterialShell, lo abordé anteriormente. El paso 1 fue asegurarse de que MaterialShell tuviera sentido y luego dividirlo en una clase base es el paso 2.

@dylanberry, la clase base realmente no lo hará mucho más fácil. No es tan simple como cambiar las plantillas de dibujo. Tengo la intención de implementar el aspecto MaterialShell de esto en el código específico de la plataforma para un rendimiento óptimo.

Los gestos de

@mackayn, una API de Transitions / Segue está por llegar y debería aterrizar aquí pronto. Todavía estoy trabajando en algunos de los nombres de mi propuesta inicial. Ciertamente será algo que viene en fases con solo las Transiciones de página en la fase 1. Sin embargo, eso le permitirá anular las animaciones del marco. En cuanto a la suscripción. El Shell debe ser la raíz de su aplicación y no puede anidar nada más que TemplatedPage. Dicho esto, la temática del control interno está 100% bajo su control. Es poco más que un interruptor mágico para activar / desactivar las nuevas plantillas y puedes controlar ese interruptor de la misma manera que nosotros. Esto le permite optar por entrar y salir de la temática en la página, el diseño o incluso el nivel de control.

@ encrypt0r no exactamente. Piense en ello como un híbrido. Permitirá la representación, pero bajo el capó, todos los controles específicos de la plataforma están temáticos con el código de dibujo. Sin embargo, hay una escotilla de escape a Skia que podría agregarse fácilmente (aunque dudo que se acerque a una v1).

@opcodewriter ListView2 (obviamente no se llamará así) está en la hoja de ruta este año por fin. ¿Por qué un nuevo ListView? Bueno, la API original conduce a una cantidad casi ilimitada de errores y problemas que no podemos solucionar de manera efectiva sin romper por completo la compatibilidad con versiones anteriores. Cosas como Cell / ViewCell y ItemsViewy TemplatedItemsList, aunque funcionaron bien para lo que estaban destinados a 1.0, no son ni mucho menos capaces de lo que necesitan para el uso moderno de la API.

Desafortunadamente, no puedo pensar en ninguna forma de resolver esto dentro del tipo ListView en sí, y desafortunadamente no creo que la comunidad haya podido hacerlo. La mejor opción en este momento es mantener ListView como está, y luego hacer algo mucho más elegante con menos gastos generales, menos contabilidad, tipos menos extraños que no necesitan existir y confiar en los marcos de destino para hacer lo que hacen mejor.

Simplemente eliminar la antigua estrategia de reciclaje, que sería un gran cambio de ruptura de retrocompatibilidad que no podemos hacer, eliminaría una parte considerable del código base de Xamarin.Forms. ListView2 lo acercará mucho más al metal al eliminar estos elementos que estaban destinados a ser barandillas (o en el caso de Cell, la fusión impía de 2 proyectos internos diferentes) y ahora solo están lastimando a todos.

La antigua estrategia de almacenamiento en caché afecta a TODOS los procesadores que existen en la actualidad. Es la razón por la que cada renderizador admite que se cambie su elemento. Si eso desapareció según mi mejor estimación, aproximadamente el 10% de todo el código del proyecto desaparecerá. Realmente es el cáncer más grande del proyecto.

@davidortinau ¡obtienes tu propio comentario solo porque el tuyo tiene un formato tan encantador!

Si utilizo este enfoque para describir mi aplicación en el nivel superior, obtengo:

  • una aplicación con el mismo tema en todas las plataformas
  • Patrones de diseño de material (en este caso) activados por defecto
  • los últimos patrones de navegación habilitados con la configuración
  • ¿No tengo que trabajar para personalizar Entry o Button para que tengan el mismo aspecto en iOS, Android y UWP?

¿Es eso exacto? ¿Otros beneficios que debo destacar?

Si, eso es correcto. Hay muchos otros beneficios que puede resaltar, pero deberían volverse obvios una vez que comience a jugar con ellos. Al igual que puede hacer hojas inferiores, tener un FAB, navegar usando URL (la actualización aún está por venir) y mucho más.

En lugar de la aplicación, tengo MaterialShell. ¿Necesito aprender / adoptar un nuevo paradigma de aplicación de nivel superior para beneficiarme de esto?

Incorrecto. Su página principal de aplicaciones es MaterialShell. La aplicación sigue siendo la raíz de su aplicación.

Una vez que estoy en mi aplicación, estoy de vuelta en la tierra de ContentPage, ¿correcto? Pero todos mis Buttons y Entrys son bonitos y materializados.

Con la excepción de donde se equivocó anteriormente, sí, esto es correcto.

¿Puedo seguir en OnPlatform y similares para diferir el aspecto (o el comportamiento) para ser diferente en otra plataforma?

Si.

¿Cómo se ve mi ruta de migración desde una aplicación existente hasta el uso de este "shell"?

Mire el caso de reproducción de Google Play Store, imagínese poner todas las páginas actuales de sus aplicaciones allí. Esto solo reemplaza aquellas áreas en su aplicación donde está usando directamente las páginas Nav / Tab / MD. No tiene ningún impacto en sus ContentPages.

Presento el nuevo MaterialShell, describo cómo quiero que se estructura y se vea mi aplicación, y simplemente la ejecuto para ver la nueva bondad.

Bingo

¿Cuáles son mis opciones si me gusta cómo se ven el menú desplegable o los elementos del menú, pero necesito modificarlos para que coincidan con las composiciones de mis diseñadores?

Usted controla completamente el encabezado, cómo se colapsa y se esconde el encabezado. Usted controla completamente la apariencia de cada una de las "Células" (no serán células) en el menú desplegable. También controlas completamente el encabezado de cada grupo allí. De hecho, usted controla el "aspecto" de todo, sin embargo, aún necesitamos agregar un par de lugares adicionales para que coloque contenido adicional.

¿En qué momento estoy diciendo "Uf, debería haber rodado todo esto yo mismo" y moviendo lo que tengo a una estructura de aplicación estándar de Xamarin.Forms?

Si el menú lateral de diseño físico de Google Play Store se ve completamente diferente de lo que desea. No es marginalmente diferente, completamente diferente.

Si tengo que abandonar totalmente el MaterialShell, ¿pierdo toda esa bondad de estilo y vuelvo a donde comencé (como hoy) con una entrada que se ve bastante diferente entre iOS, Android y UWP? Me gustaría no hacerlo.

No MaterialShell solo está configurando algunos recursos predeterminados para que sus hijos los obtengan. Podrás hacerlo tú mismo. Es posible que tenga que hacerlo de todos modos, en realidad no nos hemos comprometido a hacer que MaterialShell lo haga de forma predeterminada. Si lo hacemos opt-in en lugar de opt-out, será una única llamada a la API para cualquier subárbol.

Hay un punto de inflexión que estoy anticipando. Después de haber usado este enfoque para ponerme en marcha rápidamente, llegaré a algunas limitaciones y necesitaré explorar mis opciones. ¿Qué son y en qué momento es mejor no usar MaterialShell?

La intención es que NUNCA esté mejor si no es Shell. Es posible que no desee Material, pero siempre debe querer Shell (nuevamente, la clase base Shell está por llegar). ¿Por qué? La apariencia de shell será mucho más configurable, la historia de navegación será mucho más unificada, no debería haber nada sensato que puedas hacer con las otras páginas que no puedas hacer con Shell.

Mejor aún, la intención es asegurarse de que los renderizadores de Shell se configuren fácilmente y estén cuerdos. Sin clases mágicas ocultas, ni subclases de vistas nativas personalizadas en las que nos dedicamos a profundizar. En la medida de lo posible, todos los componentes de los renderizadores serán compuestos e intercambiables. De esa manera, si no funciona como quieres, puedes arreglarlo ...

¿Por qué no hicimos eso al principio? No era un objetivo de diseño en los primeros días y luego terminamos casados ​​con eso ... Esto es lo suficientemente grande y lo suficientemente nuevo como para que no tengamos que llevar ese error con nosotros.

@opcodewriter

En serio, ¿en cuántas direcciones diferentes puede ir Xamarin Forms? El equipo de XF apenas puede seguir arreglando la implementación actual de XF para al menos Android e iOS, ¿y ahora esto?

¿Qué pasa con la corrección de errores, la corrección de la vista previa de XAML, y el rendimiento?

^^ Esto

@migueldeicaza

Amigos, ayer Jason y yo tuvimos una discusión sobre cómo mejorar esta especificación y haremos una gran actualización, lo dividiremos en diferentes temas.

Miguel, esto claramente va a ser un gran trabajo. No puedo hablar en nombre de todos los desarrolladores, pero puedo decirles que mi equipo quiere tres cosas: estabilidad, rendimiento y flexibilidad. Queremos que se solucionen los errores. Queremos que nuestra aplicación funcione sin problemas y queremos poder implementar los diseños que nos dan nuestros diseñadores de UI / UX sin dar la vuelta y decir "Lo siento, eso no es posible en nuestra plataforma". Esta especificación parece ir en contra de ese objetivo. Esto requerirá que se dediquen más recursos al trabajo, lo que significa que sus recursos no se liberan para trabajar en la estabilidad, el rendimiento y la flexibilidad.

¿Sería este el nuevo comportamiento / forma predeterminada de desarrollar en formas xamarin? ¿O todavía tendríamos la opción de crear nuestras aplicaciones con el aspecto y la sensación específicos de cada plataforma?

@DanielCauser, aunque sospecho que a largo plazo esto puede convertirse en la forma "predeterminada", de ninguna manera reemplazará la forma actual. Simplemente será una forma más integrada y moderna que proporcionará mucho más del shell que la gente está construyendo actualmente a mano de forma predeterminada. Además de eso, dado que proporcionaremos el caparazón como un solo control, podemos optimizar mucho sobre cómo se dibuja y presenta. Ya no tendrás 3 pases de dibujo solo para tu caparazón.

Estoy cautelosamente a favor de esta idea, siempre que las mejoras que propone se resuelvan mediante mejoras en el código subyacente de Xamarin Forms. Si esto agrega más complejidad a los formularios, no lo usaría.
Sin embargo, por mi dinero, preferiría tener recursos de desarrollador dirigidos a hacer que los formularios sean más flexibles, más rápidos y terminados de lo que es actualmente. Si eso sucediera, podría hacer todas las nuevas funciones propuestas aquí por mí mismo. En este caso, es casi seguro que el bricolaje se adapte mejor a mí y a mis clientes que un kit de herramientas genérico proporcionado por Xamarin, por muy bueno que sea. Con un par de notables excepciones, esta propuesta no resuelve los problemas a los que me enfrento en este momento.

@jassmith

  1. Hay más de 500 problemas abiertos.
  2. Xamarin Forms tiene 3 años y todavía hay errores en los controles básicos y la funcionalidad, aún faltan características importantes y el rendimiento aún no se ha definido por completo (sé que se realizaron algunas mejoras, pero el rendimiento en Android es notablemente insatisfactorio).
  3. El equipo de desarrollo de Xamarin Forms todavía tiene un tamaño insuficiente.

¿Por qué quiere empezar a trabajar en esta nueva función ahora? ¿No tiene más sentido enfocarse en lo anterior primero?

Acerca de su comentario anterior relacionado con ListView: aplaudo cualquier tipo de versión audaz, incluido el rediseño / reemplazo por completo. No es que todo sea tan bueno en Xamarin Forms, las cosas no deberían tocarse \ cambiarse.

@opcodewriter

1) Sí, los hay. Estoy de acuerdo en que es un problema y seguirá siendo el elemento de trabajo prioritario por el que personalmente presiono.

2) El rendimiento en Android es parte de la razón principal de esto. Esto le da al marco más tiempo de aviso para las transiciones de página para que podamos ocultar cosas como el tiempo JIT. Podemos cargar y retener páginas de forma proactiva de forma mucho más inteligente. Lo que el equipo de XF no puede arreglar es el tiempo total de JIT. Si ejecuta su aplicación en Android con AOT habilitado y es mucho más rápido, no hay nada que pueda hacer para ayudarlo.

3) No hay argumentos aquí.

¿Por qué quiere empezar a trabajar en esta nueva función ahora? ¿No tiene más sentido enfocarse en lo anterior primero?

Este trabajo no está programado, solo estamos discutiendo una especificación aquí. Mi gerencia lo programará cuando lo considere apropiado con mi consejo.

Acerca de su comentario anterior relacionado con ListView: aplaudo cualquier tipo de versión audaz, incluido el rediseño / reemplazo por completo. No es que todo sea tan bueno en Xamarin Forms, las cosas no deberían tocarse \ cambiarse.

ListView realmente es el error de Xamarin.Forms. De esos 500 problemas, 220 de los cuales están marcados como errores (también hay muchos problemas de limpieza o mejora), al norte del 25% solo tienen que ver con ListView. A modo de comparación, eso es aproximadamente el mismo porcentaje que tiene que ver con toda la plataforma UWP. Peor aún, un buen número de los bloqueadores en Android que se describen básicamente como renderizador que se usa después de la eliminación también son errores de ListView, sin embargo, es poco probable que aparezcan en mi búsqueda, ya que ListView no aparecerá en ninguna parte de la consulta de búsqueda.

@jassmith además de solucionar problemas existentes (además de ListView, hay otras cosas que aún no siempre funcionan bien), también hay características importantes que se dejaron de lado (orden aleatorio):
- Verdadera compatibilidad con ventanas emergentes (aún falta la característica básica y común)
- Cancelar la navegación de la página al navegar hacia atrás (problema pendiente desde hace mucho tiempo)
- Faltan controles básicos (sin CheckBox, RadioButton y más)
- Dibujo multiplataforma (control de lienzo o de alguna otra manera)
- Soporte para dibujo multiplataforma de pinceles sólidos / degradados (SolidColorBrush, GradientBrush)

Desearía que se hiciera más trabajo en la dirección de hacer que el marco sea realmente más rico y no agregar cosas como el estilo CSS o Flexbox (que venían con sus propios problemas).

@opcodewriter

Verdadera compatibilidad con ventanas emergentes (aún faltan las funciones básicas y comunes)

Justo, nunca parece tener una prioridad lo suficientemente alta como para volverse real. En realidad, esto llegó bastante lejos en un momento.

Cancelar la navegación de la página al navegar hacia atrás (problema pendiente desde hace mucho tiempo)

En realidad, esto es algo que MaterialShell pretende abordar. Hay razones bastante sólidas por las que esto no se puede hacer en NavigationPage.

Faltan controles básicos (sin CheckBox, RadioButton y más)

Algunos de estos son parte de la iniciativa F100 que se está llevando a cabo ahora.

Dibujo multiplataforma (control de lienzo o de alguna otra manera)

Esa sería la API hermana para esto como se especifica en # 2452

Soporte para dibujo multiplataforma de pinceles sólidos / degradados (SolidColorBrush, GradientBrush)

Misma respuesta que la anterior.

@jassmith

Justo, nunca parece tener una prioridad lo suficientemente alta como para volverse real. En realidad, esto llegó bastante lejos en un momento.

De acuerdo, espero poder priorizarlo para fines de 2018 :)

En realidad, esto es algo que MaterialShell pretende abordar. Hay razones bastante sólidas por las que esto no se puede hacer en NavigationPage.

¿Podría dar más detalles por qué esto no se puede hacer en la implementación actual?

Algunos de estos son parte de la iniciativa F100 que se está llevando a cabo ahora.

Veo. Dedos cruzados..

¿Podría dar más detalles por qué esto no se puede hacer en la implementación actual?

No entraré en esto más aquí porque nos estamos desviando enormemente, pero la esencia es la siguiente:

  • No puede cancelar el gesto de deslizar hacia atrás en iOS de forma reactiva. Dado que este es el método principal que la gente usa para navegar hacia atrás con los teléfonos más grandes, esto se convierte en una omisión evidente.
  • Si bien es técnicamente posible anular este comportamiento en iOS, requiere profundizar bastante en los aspectos internos del UINavigationController de una manera que no podemos estar seguros de que realmente sea compatible o funcione cuando salga una nueva versión de iOS. En resumen, Apple realmente no parece disfrutar mucho que la gente haga esto.

También hay algunas otras preocupaciones menores con respecto a cómo afecta el estilo. Sin embargo, esa es la larga historia corta. Si aún desea discutir esta característica en particular, le sugiero que abra un nuevo número :)

@jassmith
Pensé que solo manejar gestureRecognizerShouldBegin y llamar a algo como OnBackButtonPressed debería ser suficiente.

En general, me gusta mucho de lo que estoy leyendo, sin embargo, esto no se siente como algo que deba hacerse en el núcleo / repositorio de Xamarin Forms.

Este es un enfoque obstinado que debe construirse sobre Xamarin Forms, no integrado en él. Veo esto como una biblioteca separada que permite a los desarrolladores adoptar un enfoque diferente. Las partes requeridas de Xamarin Forms que deben exponerse deben ser, y esto debe construirse sobre esos bits.

Al igual que cuando los desarrolladores toman la decisión de usar Xamarin Classic / Native o Xamarin Forms, puedo ver una decisión similar de usar Xamarin Forms o Xamarin Forms con Shell.

Xamarin Forms debe centrarse en crear el mejor marco de interfaz de usuario multiplataforma sin intentar adaptar las plataformas para que se parezcan entre sí. Hoy, Xamarin Forms hace un gran trabajo asegurándose de que se respete la sensación de la plataforma.

Pude ver un Shell base en el repositorio de Xamarin Forms y algo de código sobre el manejo de Shells, pero Material Shell parece estar demasiado acoplado a un lenguaje de diseño específico y un patrón de navegación para pensar que debería estar en el repositorio de Xamarin Forms.

@MisterJimson
Gracias por tus comentarios. La ubicación exacta de la superficie de la API pública aún no está decidida. Hay pros y contras de ambos enfoques.

La especificación se actualizará (con suerte muy pronto) para tener tanto una clase Shell como una clase MaterialShell. La clase MaterialShell sería la parte que consideramos sacar del núcleo. Shell sería lo que ha descrito.

Actualizado con actualización de especificaciones de navegación y ruptura de Shell

Realmente me gustaría que la implementación de XF existente se hiciera ... más fuerte y mejor para permitir que algo como esto exista como un complemento, no como parte de BCL. Por lo tanto, tener una plataforma subyacente sólida que sea correcta y estable beneficiará a las aplicaciones existentes y a cualquier capa nueva como esta.

Esperando la evolución de esta cosa.

@jassmith @brianlagunas

Solo unas pocas observaciones.

  • BackButtonBehavior, seguramente debería haber una propiedad de visibilidad en caso de que no la desee en absoluto.
  • El esquema de navegación de Materialshell es como Prism, ¿funcionará con estos marcos existentes? (Prisma, FreshMVVM, MVVMCross)
  • ¿Puede anular completamente el diseño en la barra de navegación? Tal como está, Forms es extremadamente limitado en este sentido y terminas con barras de navegación de aspecto tosco que te obligan a seguir la ruta de customrenderer, sabiendo que una nueva versión de Forms probablemente romperá tu código personalizado.
  • MasterDetail no se toca mucho, ¿podrá personalizar el menú desplegable?
  • ¿Qué control tendremos sobre la hamburguesa?

Solo quiero asegurarme de que se aborden los puntos débiles y las limitaciones existentes, así como las nuevas capacidades.

Suena genial.

Soy muy nuevo en XF, pero el marco tiene cierta reputación de ser algo frágil, aunque ciertamente esto está mejorando rápidamente gracias a sus esfuerzos.

Entonces, por lo que vale, esta es mi opinión :-)

Es genial que Xamarin reciba mucho cariño en este momento, pero estoy de acuerdo con @opcodewriter , tanto las herramientas como el marco podrían

También me gustan los pensamientos de @MisterJimson de que esta debería ser una capa diferente, pero deben ser honestos con ustedes mismos sobre su capacidad y cuántos marcos pueden soportar. Todos somos propensos a codificar cosas nuevas y emocionantes y a evitar las decisiones difíciles, pero confiamos en usted para desarrollar una base sólida para nuestro código.

Tengo suficientes problemas para que mi código funcione sin preocuparme por el de otra persona :-)

XF está en un buen lugar en este momento, tiene el potencial de convertirse en un conjunto de herramientas realmente sólido.

Gracias por todo su arduo trabajo en esto, se nota.

@mackayn

BackButtonBehavior, seguramente debería haber una propiedad de visibilidad en caso de que no la desee en absoluto.

Establezca el comando con CanExecute devolviendo falso. Opté por no agregar un método secundario por el momento.

El esquema de navegación de Materialshell es como Prism, ¿funcionará con estos marcos existentes? (Prisma, FreshMVVM, MVVMCross)

¡Seguro espero eso! No puedo estar seguro, pero estaba pensando en ellos y en todos sus problemas. Es por eso que toda la navegación ocurre a través de un solo evento, por ejemplo.

¿Puede anular completamente el diseño en la barra de navegación? Tal como está, Forms es extremadamente limitado en este sentido y terminas con barras de navegación de aspecto tosco que te obligan a seguir la ruta de customrenderer, sabiendo que una nueva versión de Forms probablemente romperá tu código personalizado.

Esta parte es más difícil. Me gustaría permitir tanta extensibilidad aquí como sea posible, pero estoy realmente abierto a sugerencias sobre cómo mejorar esto de una manera sensata y razonable.

MasterDetail no se toca mucho, ¿podrá personalizar el menú desplegable?

Puede establecer el encabezado en cualquier vista arbitraria, controlar la plantilla utilizada para los encabezados y elementos de grupo y puede agregar elementos de menú. Controlas algunos aspectos del diseño, pero no el 100%. Una vez más, sería bueno tener algunas ideas sobre qué más cree que necesita. Veo claramente la necesidad de un pie de página con una propiedad de comportamiento de pie de página.

¿Qué control tendremos sobre la hamburguesa?

BackButtonBehavior también anula la hamburguesa. Quizás debería cambiarse el nombre. Nuevamente estoy abierto a sugerencias aquí. Originalmente lo llamé LeftBarButton, pero en situaciones de RTL no está a la izquierda ...

La amortización técnica de

Las interacciones estrechas entre la barra de pestañas y la barra de navegación es una de esas áreas, asegurándose de que la navegación entre pestañas o elementos en el MDP no tenga fallas es otra área. Hay muchas áreas donde se producirán pequeños contratiempos porque cada elemento no puede tener una vista holística del shell de su aplicación.

En cuanto a las herramientas, hay un equipo completamente separado dedicado a esto y están haciendo grandes avances. ¡Las herramientas internas han mejorado enormemente en los últimos 6 meses y realmente espero que pruebes eso!

@mackayn

El esquema de navegación de Materialshell es como Prism, ¿funcionará con estos marcos existentes? (Prisma, FreshMVVM, MVVMCross)

No temas, @jassmith me llamó la atención sobre esto antes de que la comunidad se diera cuenta de que el problema estaba aquí ... así que puedo decir con algo de confianza que es un problema que ciertamente le importa tanto como a nosotros. Puede estar seguro de que será algo que buscamos apoyar. Algo de esta magnitud ciertamente requerirá muchos diálogos entre equipos para garantizar que satisfaga las necesidades del desarrollador de Forms en general, así como también las necesidades de los marcos MVVM como Prism.

@dansiegel

Es bueno saber que ambos equipos están en diálogo, eso es todo lo que necesitaba saber 👍

@jassmith Es obvio a estas alturas que la forma en que algunas cosas se están ejecutando o se diseñaron en XF no es la mejor. Entonces, en lugar de poner lápiz labial en el cerdo (sin querer ser grosero aquí), ¿por qué no recrear un nuevo marco desde cero o refactorizar masivamente el existente? Lo sé, suena muy aterrador, pero estoy bastante seguro de que a la gran mayoría de los desarrolladores de Xamarin Forms no les importaría, todos estaríamos emocionados de refactorizar nuestras aplicaciones o lo que sea para tener aplicaciones que se ejecuten mucho mejor.
He visto PR rechazado con una buena refactorización porque "no queremos este tipo de cambios". No estoy seguro de quién hizo esa regla, pero debería respirar profundamente, relajarse y quizás reconsiderar la "regla".
¿Qué es lo mejor? ¿Seguir teniendo desarrolladores frustrados que utilizan un marco que no puede seguir el ritmo o tener desarrolladores frustrados que necesitan hacer un trabajo de refactorización? Solo mis 2 centavos ...

@opcodewriter, usted y yo estamos de acuerdo, pero esto es fuera de tema para esta especificación.

Solo leí el nuevo material sobre navegación y realmente me gustó. Me encanta tener una mano ordenada para vincular comandos de navegación, y orientar la navegación alrededor de las URL (como y supongo que está influenciada por Prism) es inteligente.

Irónicamente, el esquema de navegación de URI era algo que queríamos hacer hace mucho tiempo y comenzamos a presionar a Prism para que lo implementara porque no podíamos introducirlo razonablemente en el marco. Para no tomar nada de su crédito, se merecen el 100% de eso :)

La semántica exacta de la taquigrafía todavía está en juego.

Creo que probablemente terminará más como:

<Button Command="{segue:Uri}" CommandParameter="app://Foo/Bar/Baz" />

o

<Button Command="{segue:Push}" CommandParameter="{DataTemplate local:MyPage}" />

Por lo que las extensiones pueden ser más precisas sobre los parámetros que toman. El espacio de nombres se utiliza principalmente para que las cosas sean fáciles de descubrir con intellisense.

@jassmith Me gusta mucho este material de segue. ¿Puedo preguntar cómo piensa apoyar el modo push?

No tengo todos los detalles, pero podría imaginar la navegación de URL como un prisma, envuelto en extensiones de marcado.

<!-- push -->
<Button Command="{segue:Uri}" CommandParameter="path/to/page" />

<!-- push modal -->
<Button Command="{segue:Uri Modal='true'}" CommandParameter="path/to/page" />

<!-- reset stack -->
<Button Command="{segue:Uri}" CommandParameter="app://root/path/to/page" />

Lo primero a tener en cuenta es que la navegación por URI solo funcionará con Shell. Es el único lugar en el que podemos darle sentido a la pila de manera consistente sin tener casos extremos extraños y podemos diseñar las interacciones de navegación para respaldar el concepto.

Por ahora, solo admitimos URI completos. Los parciales son mucho más difíciles de tratar porque son contextuales.

Sus 3 ejemplos serían entonces, asumiendo que la ubicación actual es: app: // Shell / Apps / Games / Details

En particular, esto significa que está en un Shell, cuyo ShellItem actual tiene la Ruta de aplicaciones, cuyo ShellTabItem actual tiene la ruta de Juegos, que tiene un ContentPage insertado en su pila que tiene los Detalles de la ruta.

<!-- push -->
<Button Command="{segue:Uri}" CommandParameter="app://Shell/Apps/Games/Details/page" />

<!-- push modal -->
<Button Command="{segue:Uri}" CommandParameter="app://page" />

<!-- reset stack -->
<Button Command="{segue:Uri}" CommandParameter="app://Shell/Apps/Games" />

En un uri de shell, la primera ubicación es siempre un Shell. Si no es así, se supone que es un impulso modal. Lo siguiente es ShellTab, luego ShellTabItem. Después de eso, sigue la pila de navegación de ShellTabItem. No tengo la intención de hacer backporting de navegación URI a todos los posibles controles de página en este momento. Esto se pone REALMENTE peludo con las personas que usan MasterDetailPage's ...

Con el registro de ruta y las propiedades de ruta, no es necesario un enrutamiento basado en tipos. Voy a eliminarlo de la especificación.

@jassmith reflexionando más sobre este tema de navegación, y tengo algunas preguntas

  1. ¿cómo puedes manejar CanExecute
  2. ¿Cómo se puede dar al usuario control sobre (prevención de lectura) múltiples toques?
  3. ¿Cómo maneja la navegación relativa? Es decir, ¿tiene 3 páginas de profundidad y necesita ir a la cuarta, pero la pila es completamente dinámica?
  4. prism tiene esta fantástica noción de NavigationParameters mediante la cual podemos pasar no solo valores básicos a través de la cadena /Navigation/MyPage/MyPageDetails?id=33 consulta new NavigationParameters {{nameof(MyObject), MyObject}} . ¿Planeas apoyar algo similar?

@ChaseFlorell

1) ¿Con segues? Actualmente no puedes. Definitivamente hay que pensar más en ello. Hay una forma de hacer un comando de segue pero ... apesta. Eso te permitiría manejarlo, pero en ese momento REALMENTE no vale la pena.

2) Un Segue se desactivará solo hasta que se complete el empuje. Intentos adicionales de activar el comando no-op hasta que se complete la tarea de navegación anterior.

3) Puede utilizar una navegación tradicional como push / pop con segues. Estas son acciones relativas.

4) [QueryParameterAttribute] puede o no existir ya, no puedo confirmar ni negar. ;)

Es poco probable que agreguemos soporte para objetos complejos. La idea es que use convertidores para tomar sus valores simples y convertirlos en objetos complejos.

A partir de la experiencia pasada la construcción de la navegación aplicación basada en URI (de nuevo en el CAB-Composite UI Application Block para los gastos de envío), me gustaría sugerir fuertemente que no utiliza el System.Uri tipo y en su lugar sólo hacer que todo parezca como un URI, pero no use la implementación de URI en sí. @pprovost puede dar testimonio de las cicatrices de toda la vida que debe haberle dejado el trabajo. Recuerdo haber enfrentado innumerables problemas cuando enfrentamos restricciones y errores de URI de Internet (es decir, en los nombres de host) que no nos importaban menos las cosas dentro de la aplicación.

Supongo que parte del daño ya está hecho .

En realidad, System.Uri es la mejor opción cuando se admite un esquema de navegación basado en URI. Si bien CAB usó la navegación URI, también hizo lo que usted dice y lo hizo "parecer" un URI al permitirle usar cadenas en lugar del objeto System.Uri. Los nombres de host nunca fueron necesarios.

Lo que está pidiendo es una API basada en cadenas muy flexible que pueda aceptar cualquier sintaxis de cadena que ingrese, lo cual no es algo que produzca resultados predecibles. Debe haber reglas establecidas para que funcione un esquema de navegación basado en cadenas / URI.

Un URI arbitrario tampoco funcionará en XF. La lista de caracteres no válidos en una URL pero que son válidos en un sistema de archivos no es precisamente pequeña. Esos son todos los casos en los que una cadena habría funcionado, y un URI no lo hará y necesitará escapar o hacer que el usuario averigüe por qué las cosas no funcionan (¿o fallan?) Y cambiar el nombre de las cosas para que sean "seguras para URI".

Puede crear su propia abstracción si desea más restrictivo (¿o mejor semántica / análisis / validación?), Pero en mi humilde opinión, System.Uri trae mucho equipaje de Internet que no es gratis. Esto es similar a cómo Mono / MonoDevelop creó su propio FilePath para representar rutas, que normalmente son solo cadenas.

Al menos, parece que todos los URI se consideran relativos, lo que simplifica las cosas. En CAB usamos uris absolutas con partes de esquema y nombre de host también, lo cual fue problemático.

Prefiero algo como ResoucePath , digamos, que Uri . Pero tan tarde en el juego, estoy bastante seguro de que de todos modos está hecho un trato.

No estoy seguro de qué crees que las rutas del sistema de archivos tienen que ver con algo ...

¿Cómo usarías una URI para confundir el sistema? Va a ignorar el esquema y el nombre de host y comenzar a buscar rutas (que están limitadas a [az] solamente). Si los caracteres extraños que introduces no se pueden encontrar, simplemente se detiene. Y la cadena de consulta que ingrese debe ser identificadores C # válidos o simplemente no coincidirá. Los datos de escape en los datos de la cadena de consulta no se escaparán.

@kzu URI funciona bien en XF, y se adapta mejor a XF de lo que sería un esquema de sistema de archivos. De hecho, se espera un URI al iniciar su aplicación desde un sitio web. Debería comprobar lo poderosa que puede ser la navegación basada en URI observando la implementación de Prism. De todas las aplicaciones creadas con Prism que utilizan un esquema de navegación basado en URI, nunca se ha enviado un problema relacionado con caracteres no válidos. Estoy seguro de que sus preocupaciones sobre un esquema basado en URI para la plataforma XF no serán un problema.

Tiene sentido. ¡Gracias por la información de antecedentes sobre Prism @brianlagunas! Ahora debería leer atentamente la especificación y proporcionar algunos comentarios realmente útiles;)

Muy buena iniciativa, pero espero que se tenga en cuenta la extensibilidad y la personalización mediante la creación de los métodos virtuales adecuados u otras formas de hacer lo "especial" para nuestros clientes.

Por ejemplo, será posible / cómo:

  1. Extensibilidad de pestañas, por ejemplo, mostrando una insignia con un icono. O mostrando un cajón emergente encima de uno, como un botón "más" o " * ".
  2. Barra de bocadillos personalizada (por ejemplo, con el botón "Deshacer" para una acción que acaba de hacer con colores personalizados de fondo / primer plano)
  3. Empuje de fragmentos en Android usando animaciones diferentes a las programadas por defecto en el Shell, como sin animación para brindar la navegación más rápida posible.

En una nota técnica: ¿el shell reciclará las páginas de modo que una vez que se navegue dos veces a una página, los elementos nativos se reutilicen con una máquina virtual diferente debajo de ella?

Hola @rogihee

Agradezco sus comentarios sobre la implementación. Creo que es una locura extensible: https://github.com/xamarin/Xamarin.Forms/blob/9558f2837280e02b41848d3a3c3213d49a664751/Xamarin.Forms.Platform.iOS/Renderers/ShellRenderer.cs

Android todavía se encuentra en un gran desarrollo en este momento, sin embargo, utiliza un enfoque idéntico.

@rogihee en cuanto al reciclaje de páginas, estoy tratando de encontrar un método sensato para hacerlo viable. En general, no lo hace actualmente, ya que debería optar por participar explícitamente.

Se ven bien estas opciones de "Crear *". ¡Es bueno ver el rápido progreso en esto!

Me pregunto si hay implicaciones de rendimiento con la reutilización de elementos. Personalmente, daría prioridad a la velocidad y la sensación "fluida" de una aplicación sobre un mayor uso de Mem / CPU (aunque hay una correlación en algún lugar al final del curso). Y priorice iOS / Android sobre cualquier otro :-).

Shell se centra mucho en la percepción de fluidez. Todavía no está en su lugar en todas partes, pero se está uniendo.

Realmente necesito tener algunos usuarios tempranos que intenten hacer cosas locas con el shell para asegurarse de que pueda manejar la carga para la que está diseñado.

@jassmith mig acaba de mencionar el shell durante 3 minutos en Build .....

No soy su papi

+1

API actualizada para que coincida con el estado actual del mundo, aún es necesario actualizar las muestras.

Se agregaron algunas muestras actualizadas, todavía es necesario trabajar mucho para corregir otras muestras y actualizar las descripciones de las rutas cuando se usa la sintaxis taquigráfica (¡a medida que obtiene rutas taquigráficas!)

Dios, me siento tan tarde para la fiesta. Gran redacción y discusión. Lo hojeé todo (lo siento en el aeropuerto) y tengo una sugerencia propia. Lo siento si esto se mencionó en otro lugar.

@jassmith @migueldeicaza ¿Puede agregar un comportamiento a la barra de navegación para que se pueda desplazar cuando ListView se esté desplazando y se muestre cuando se desplaza en la dirección opuesta? Casi todas las aplicaciones profesionales hacen esto para mostrar más propiedades inmobiliarias. Esto sería especialmente útil en dispositivos pequeños.

Otro es ¿por qué no cambia el nombre de las etiquetas XAML para que sean más fáciles de entender? ¿Quizás usar Tab en lugar de ShellSection? Ahora hay muchas etiquetas ShellX.

Para iOS, creo que hay una propiedad para activar / desactivar para habilitar el modo de desplazamiento en la barra de navegación. Para Android, debe comenzar a usar los nuevos diseños (CoordinatorLayout, AppBarLayout, etc.). La implementación de Android de XF está bastante desactualizada en este sentido, ya que todavía usa un RelativeLayout como contenedor principal. Creo que hay un ticket de Mejora en alguna parte sobre este tema específico. Me encantaría ver que Shell admite diferentes modos de desplazamiento.

Además, a menudo tenemos que implementar un comportamiento personalizado para mostrar errores / otros tipos de ventanas emergentes en la página. Shell debería admitir esta funcionalidad desde el primer momento, por lo que no es necesario recurrir a complementos de terceros o crear una jerarquía de interfaz de usuario compleja.

@ adrianknight89

¿Puede agregar un comportamiento a la barra de navegación para que se pueda desplazar cuando ListView se esté desplazando y se muestre cuando se desplaza en la dirección opuesta? Casi todas las aplicaciones profesionales hacen esto para mostrar más propiedades inmobiliarias. Esto sería especialmente útil en dispositivos pequeños.

Eso es algo que realmente estoy tratando de encontrar la manera correcta de hacerlo. Desafortunadamente, no todas las plataformas admiten esta función, por lo que probablemente terminará siendo un acuerdo específico de la plataforma. Android, al menos, se construyó completamente para admitir esto, lo enciendo ocasionalmente para asegurarme de que todavía funciona.

Otro es ¿por qué no cambia el nombre de las etiquetas XAML para que sean más fáciles de entender? ¿Quizás usar Tab en lugar de ShellSection? Ahora hay muchas etiquetas ShellX.

El nombre aquí es REALMENTE difícil. ShellTab es un poco confuso para arriba y abajo. En cambio, opté por nombres jerárquicos más genéricos, sin embargo, debo admitir que no estoy contento con los nombres. Las sugerencias son 100% bienvenidas ... no estoy ansioso por refactorizar sus nombres OTRA VEZ, pero qué puedes hacer ...

Para iOS, creo que hay una propiedad para activar / desactivar para habilitar el modo de desplazamiento en la barra de navegación. Para Android, debe comenzar a usar los nuevos diseños (CoordinatorLayout, AppBarLayout, etc.). La implementación de Android de XF está bastante desactualizada en este sentido, ya que todavía usa un RelativeLayout como contenedor principal. Creo que hay un ticket de Mejora en alguna parte sobre este tema específico. Me encantaría ver que Shell admite diferentes modos de desplazamiento.

Shell usa CoordinatorLayout + AppBarLayout y básicamente "deshabilita" el soporte de desplazamiento por el momento, pero funciona. El desplazamiento de iOS también es fácil de implementar. Lamentablemente, NavigationView de UWP no admite esta función.

Además, a menudo tenemos que implementar un comportamiento personalizado para mostrar errores / otros tipos de ventanas emergentes en la página. Shell debería admitir esta funcionalidad desde el primer momento, por lo que no es necesario recurrir a complementos de terceros o crear una jerarquía de interfaz de usuario compleja.

Ejemplos, necesito ejemplos :)

@jassmith

Estoy usando el complemento de conectividad de James Montemagno para escuchar los cambios en el estado de la conexión de datos. Cuando la conexión a Internet se interrumpe, es una buena práctica mostrar una notificación que se desliza, aparece y desaparece o permanece inmóvil hasta que Internet vuelve a estar en línea.

En Instagram, esta notificación se coloca justo debajo de la barra de navegación. En Tumblr, está justo encima de la barra de navegación inferior. En YouTube, extrañamente está debajo de la barra de navegación inferior. ¿Quizás algo como esto pueda ser parte de Shell?

El control emergente propuesto, hasta donde yo sé, se superpone a la ventana existente, aunque puede ser fácil de descartar. La notificación que acabo de mencionar y potencialmente otros tipos de notificaciones no necesitan superponerse a su ventana principal (es decir, el árbol visual principal todavía responde a los gestos), por lo que no estoy seguro de si Popup es el adecuado.

Shell puede tener una propiedad para que definamos cómo se verá esta Vista (llamémosla Notificación [Vista]), así como su ubicación y comportamiento de animación de entrada / salida. Esencialmente, una implementación multiplataforma de tostadas / snackbar incorporada en Shell, INavigation u otra cosa. Esto no estaría obligado a parecer nativo por plataforma, pero igual en todas.

d1c014c0-fc7b-4788-9689-1948a7294426

bc91d3ca-b95f-4485-a917-db6ab47510c1

Con respecto a los argumentos que se están haciendo en torno a la estabilidad, la flexibilidad, etc., sin deshacerse de la arquitectura obsoleta proveniente de 1.0, no creo que sea factible lograr esas cosas. Estoy muy a favor de ListView2.

@jassmith

  • ¿Tiene un ticket de mejora para el nuevo ListView todavía?
  • ¿Cuándo crees que saldrá la v1.0? ¿Alguna posibilidad de que podamos verlo por EOY?

Además, tengo la misma preocupación sobre el tamaño del equipo. De hecho, mencioné esto antes en el pasado. Espero que el equipo pueda crecer mucho más en el futuro. 🙏 @davidortinau @migueldeicaza

@jassmith He creído desde hace un tiempo que si tuviéramos un Renderer para la clase App, podríamos hacer muchas cosas que actualmente requieren piratería de terceros para lograrlo. Por ejemplo, el complemento RgPopups toma la vista principal de la aplicación e inyecta vistas renderizadas en ella para proporcionar una apariencia emergente de pantalla completa. Esto es actualmente imposible de lograr con Xamarin Forms "puro". Sin embargo, si la aplicación tuviera un renderizador, podríamos hacerlo nosotros mismos.

Estoy totalmente a favor de agregar este tipo de notificaciones tostadas a Shell, solo tratando de averiguar cómo se debe hacer.

¿Puede hacer que pueda colocar páginas arbitrariamente donde quiera dentro de una aplicación? Esto es especialmente importante en tabletas / computadoras de escritorio / portátiles (dispositivos de pantalla más grande), donde desea que aparezcan varias páginas en la pantalla al mismo tiempo y no necesariamente desea organizarlas usando una vista dividida (página de detalles maestra). Por ejemplo, consulte Google Maps:

image

Observe cómo el contenido "flota" en la parte superior del mapa (sin vista dividida). Si desea usar cosas como pestañas o navegación dentro del área flotante, entonces no puede lograr este tipo de cosas con Xamarin Forms, listo para usar, debido a la jerarquía extremadamente limitada con páginas (no se puede anidar una página dentro de una vista). De hecho, desarrollamos nuestra propia vista personalizada que proporciona capacidades similares a NavigationPage pero es una vista, solo para poder lograr este tipo de diseño, pero fue mucho trabajo / difícil de hacer.

Debería ser posible colocar contenido (incluidas las páginas) en cualquier lugar que desee dentro de una aplicación.

¿Puede hacer que pueda colocar páginas arbitrariamente donde quiera dentro de una aplicación?

Soy un poco curioso, @jsiemens, ya que esta vista probablemente no se vería bien en un teléfono, pero se vería muy bien en una

@dansiegel Al menos personalmente, probablemente usaría VSM o algo equivalente para mover y compactar la vista de desplazamiento en la parte inferior cuando esté por debajo de un cierto umbral de ventana gráfica (como lo hace GMaps actualmente). Sin embargo, sería curioso ver cómo funcionaría la navegación y la gestión del estado para eso.

Navegación: Estoy seguro de que ese no es un problema insuperable si comenzaste desde la perspectiva del viaje del usuario y luego miraste cómo el usuario esperaría que funcionara. La navegación debería responder a la naturaleza de pantalla completa de un teléfono frente a una vista más pequeña en una pantalla más grande, por ejemplo.

El usuario "vería" la tableta y la vista más pequeña como un solo hito de navegación. En una pantalla pequeña podría haber dos hitos. La navegación, de alguna manera, tendría que ser receptiva.

Como desarrolladores, seguramente tenemos que manejar esa naturaleza receptiva, ya que es algo contextual. No podemos confiar en el marco para manejar eso por nosotros, pero el marco debe respaldarlo.

@jsiemens @dansiegel La forma en que manejo esto actualmente es usando ControlTemplate s. Construyo mi contenido de tipo "página" como ContentView sy los alojo en un ContentPage (dentro de un NavigationPage ) que es apropiado para la plataforma. Usar ControlTemplates significa que puedo tener varios ContentViews enlazados (generalmente en un Grid para poder superponer cosas) que se encienden / apagan según las propiedades enlazables en el ControlTemplate sí mismo (también puede usar DynamicResource s). El resultado final funciona un poco como los paneles CSS en un sitio web, donde todo el contenido está en la página pero no todo es visible todo el tiempo. ControlTemplate s son mágicos para esto y me gustaría que sus capacidades se conservaran en Shell.

@dansiegel Simplemente lo codificaría para cargar un shell diferente dependiendo de si la aplicación se estaba ejecutando en un teléfono o en una tableta / computadora portátil / computadora de escritorio.

@jsiemens está bien, mi comentario solo tiene la intención de estimular una mayor conversación y pensamiento crítico para refinar aún más su idea. De alguna manera, casi diría que dado su concepto aquí, cada página podría ser esencialmente una página múltiple en la que una página podría adjuntarse a un control dado y tratarse más como otra vista en comparación con la navegación normal.

@dansiegel Sí, creo que eso es lo que busco es poder agregar una página en cualquier lugar dentro de la aplicación. Es extraño que Xamarin Forms imponga esta limitación cuando las plataformas subyacentes no lo hacen (por ejemplo, iOS es solo una jerarquía de vistas en árbol; puede agregar la vista de NavigationController literalmente en cualquier lugar dentro de la aplicación). Además, mi comentario tenía la intención de indicar que no es necesario que la especificación de Shell cubra esto; no creo que el diseño "receptivo" deba ser una preocupación. Creo que mientras sea posible construir el diseño, entonces podemos encargarnos de cargar shells de forma condicional según el factor de forma, y ​​eso es lo suficientemente bueno.

Supongo que no está del todo en el tema de esta especificación, pero lo mencioné aquí porque estamos hablando de cómo construir diseños complejos (por ejemplo, la tercera prioridad de @MelbourneDeveloper : flexibilidad), y este es ciertamente un diseño que es superior mente para mí y para mi equipo (estamos creando una aplicación de mapeo en la que queremos poder colocar paneles de contenido flotantes en la parte superior del mapa, que podrían contener contenido "solo de página", como páginas de navegación y pestañas).

No sé cómo se resolvería esto usando shell, pero mi reacción inicial a shell es que no parece hacer nada que yo no pueda hacer ya. En general, siento que el equipo de Xamarin Forms sigue creando características que me permiten hacer cosas que ya podía hacer, pero de una manera diferente (por ejemplo, CSS, Visual State Manager y ahora las especificaciones de dibujo y shell). Así que eso no me aporta mucho valor. Prefiero tener nuevas funciones que me permitan hacer cosas que antes no podía (fuera de los controles personalizados y / o renderizadores). Si shell es la respuesta para lograr eso porque la sintaxis es más elegante, entonces estoy totalmente de acuerdo, pero en última instancia, me gustaría que fuera más poderoso y más expresivo que la jerarquía de página / vista actual, ya que realmente aporta valor.

¿Podría desacoplar la creación de una vista nativa por vista xamarin si todas las subvistas dentro de un diseño se pueden renderizar sin usar widgets nativos? Es una especie de enfoque híbrido automático de flutter / xamarin en el que los grupos de vistas XF se representan en una sola superficie y simplemente se borran en una vista nativa. Sería útil evitar la creación / diseño de la vista de Android c # -> costo de interoperabilidad de Java.

¡¡en curso!!

@jassmith después de que termine el shell, ¿el sorteo será válido en conjunto?

¿Shell va a admitir macos y wpf?

@juepiezhongren los objetivos iniciales son iOS y Android. Después de eso, se priorizarán otras plataformas.

El dibujo no se está desarrollando actualmente. En su especificación actual, sería válido con Shell. Al igual que hoy, puede usar los controles basados ​​en SkiaSharp y Skia dentro de Xamarin.Forms.

Estamos trabajando en otras estrategias nativas para respaldar el diseño coherente de materiales y otros estilos de diseño.

@davidortinau ¿El shell mejora la compatibilidad con RTL?

¿Mejor de qué manera? ¿Qué le falta al soporte RTL hoy? Deberíamos abordarlo en todas partes.

Para ser honesto, no he realizado el desarrollo de XF en un tiempo, pero la mayoría de las limitaciones son conocidas: eche un vistazo a # 1222 y # 2448

Tal vez shell pueda ayudar con estas limitaciones generales:

  • La ubicación del botón NavigationPage, la ubicación del elemento de la barra de herramientas y la animación de transición están controladas actualmente por la configuración regional del dispositivo, no por la configuración de FlowDirection.
  • Configuración de la aplicación global para FlowDirection

Y algunas otras limitaciones específicas de la plataforma

Característica más importante de Xamarin.Forms. Debería haber sido construido así en primer lugar.

sin dibujar, xf todavía falta bastante

@juepiezhongren

Solo usa Skiasharp

@mackayn lo usé mucho
https://github.com/xamarin/Xamarin.Forms/issues/1789
el aspecto universal es imprescindible

Adam se puso a revolotear, es realmente una señal triste para xf, donde xamarin originalmente podría fácilmente lograr una reputación mucho mejor

xamarin.native es mucho más sólido para xf que cualquier otra solución multiplataforma, independientemente de las reacciones nativas o flutter. Como amante de dotnet, la situación actual de xf siempre me decepciona un poco.

@juepiezhongren

Esta discusión no tiene sentido, si no satisface sus necesidades, use Flutter, nos permite entregar aplicaciones en múltiples plataformas (iOS y Android solo con Flutter, etc.), estos cambios harán que una apariencia consistente sea más alcanzable.

pequeñas quejas sencillas, demasiado. ¡Todavía hurra por la concha!

Estoy de acuerdo en que sería mejor tener Skia mucho más integrado en la API de Forms (como lo ha hecho Telerik). Estoy de acuerdo.

Sin embargo, me alegra que estén invirtiendo el esfuerzo en Shell & CollectionView.

hola, por favor, todos digan, ¿cómo puedo usar Flayout en derecho, para el idioma de derecha a izquierda?

Hola,

Me encanta la idea, pero solo tengo algunas pequeñas aportaciones.
Supongo que llego un poco tarde, pero creo que el nombre es un poco confuso.

  1. El elemento, la sección y el contenido son todos nombres realmente generales. No está claro de inmediato en qué relación están. ¿Es Contenido => Sección => Artículo o Sección => Contenido => Artículo, o Artículo => Sección => Contenido?
    Así que podríamos especificar un poco más cuáles son las diferentes "cosas", encontrando un nombre más específico.

  2. Eso me lleva a la siguiente entrada. Tenemos un Shell como contenedor para todos los elementos internos. Entonces, ¿no podemos usar nombres sencillos como "Item" en lugar de "ShellItem" dentro. Me parece un poco innecesario llamar a todas las "cosas" Shelltem, ShellSection, etc. pero está bien. eso es discutible.

Ay

¿Seguirá siendo lanzado en 2018?

¡Tenemos una versión preliminar disponible AHORA! Eche un vistazo a https://blog.xamarin.com/connect-2018-xamarin-announcements/ para ver algunos ejemplos excelentes.

¿Realmente necesitamos Android 9? Eso parecería ser una limitación.

Todo suena bastante bien, pero parece basarse puramente en la interacción de la interfaz de usuario.
Supongo que lo averiguaré cuando lo pruebe, pero mi preocupación inicial es cómo manejo la navegación desde la lógica comercial o el código, por ejemplo, los mensajes recibidos desde un dispositivo conectado por Bluetooth que provocan un cambio de página, mientras mantengo una separación decente de preocupaciones.

@hassanrahimi

hola, por favor, todos digan, ¿cómo puedo usar Flayout en derecho, para el idioma de derecha a izquierda?

Si bien se admite RTL, el menú desplegable aún aparece a la izquierda. Ésta es una limitación actual.

¿Es posible personalizar la interfaz de usuario de la barra de pestañas inferior?

¿Es posible agregar controles al shell que no se recargan cuando se navega dentro del shell? Por ejemplo un FAB ..

La interfaz de usuario de la barra de

La adición de controles que son globales como usted describe como un FAB está planificada para MaterialShell. ¿Puede proporcionar escenarios adicionales que se beneficiarían de esto además de FAB?

Primero: he usado mi propio caparazón antes, ahora puedo fácilmente reemplazar el mío con el tuyo y es mucho mejor. Me gusta mucho.

Probablemente mis casos sean personalizados y no relacionados con el shell, pero:

Caso uno:
Si quiero crear una aplicación con un menú muy personalizado, un botón de menú en cada esquina de la aplicación, ¿cómo agrego los botones para que formen parte del caparazón (como superposición o cartelera)? No quiero que vuelva a rendirse cada vez que navego.

Caso dos:
Quiero usar el caparazón pero quiero personalizar la barra de pestañas inferior para que el botón central sea más alto (llamado botón central elevado). ¿Debo usar el renderizador y personalizar la vista de navegación inferior?

¿Crees que debería usar el caparazón para casos especiales como este?

Por supuesto, considero hacerlo en cada plataforma, pero los menús deberían verse iguales en todas las plataformas, así que quiero compartir el código.

Aquí están mis comentarios. Hago esta prueba ( Xamarin.Forms 4.0.0.8055-pre1 ):

   <Shell.FlyoutHeader>
        <local:FlyoutHeader />
    </Shell.FlyoutHeader>

    <ShellItem Title="Home" Icon="home.png">
        <ShellSection>
            <ShellContent>
                <local:MainPage />
            </ShellContent>
        </ShellSection>
    </ShellItem>

    <ShellItem Title="Notifications" Icon="notification.png">
        <ShellSection>
            <ShellContent Title="Recent">
                <local:NotificationPage />
            </ShellContent>
        </ShellSection>
    </ShellItem>

    <ShellItem Title="Test" Icon="icon.png">
        <ShellSection Title="Home" Icon="home.png">
            <ShellContent>
                <local:MainPage />
            </ShellContent>
        </ShellSection>

        <ShellSection Title="Notifications" Icon="notification.png">
            <ShellContent Title="Recent">
                <local:NotificationPage />
            </ShellContent>

            <ShellContent Title="Settings">
                <local:SettingsPage />
            </ShellContent>
        </ShellSection>
    </ShellItem>

Todo funciona cuando tocamos el menú de hamburguesas. Sin embargo, si vamos al menú Test y tocamos Home y Notifications un lado a otro y elegimos entre Recent o Settings , la página se abrirá respectivamente. Pero luego, cuando volvemos a tocar el menú de hamburguesas, la aplicación se bloquea.

image

¿Cómo podemos usar GroupHeaderTemplate para mostrar un título para un grupo de ShellContent en un ShellItem?

Para muchos usuarios está claro que Xamarin Forms no se puede mantener en su tamaño y complejidad actuales, por lo que cualquier cosa nueva debería disminuir la complejidad en lugar de aumentarla.

@jassmith La intención es que NUNCA esté mejor si no es Shell. ... La intención es asegurarse de que los renderizadores de Shell se configuren fácilmente y estén cuerdos.

Si se completa Shell, ¿qué se puede depreciar en el futuro y, cuando se hace, se reduce la complejidad general de Xamarin Forms? ¿Se depreciarán todas las demás páginas, excepto ContentPage?

La estrategia debería consistir en sacar el máximo partido posible del repositorio. La estabilidad y capacidad de mantenimiento del repositorio principal es lo más importante.

Además, ¿hay alguna razón por la que Shell no se llame ShellPage? Otras clases de página tienen nombres que terminan en "Página".

El anuncio actual de Shell (en https://blog.xamarin.com/xamarin-forms-4-0-preview/) no es prometedor.

  1. Una forma simplificada de expresar el alto nivel de la arquitectura de su aplicación

Esto lleva a Xamarin más allá de su propósito real. Xamarin no es necesario para la arquitectura de la aplicación. Esto debería ser solo sobre el diseño.

  1. Una jerarquía de patrones de navegación de IU comunes que se adaptan a sus plataformas móviles objetivo

Espero que "mobile" sea un error de imprenta aquí porque Xamarin.Forms también cubre los escritorios.

  1. Un servicio de navegación robusto

Xamarin.Forms no necesita navegación. Si la navegación actual no funciona, simplemente se puede depreciar porque hay muchos enfoques buenos para la navegación que no requieren nada integrado.

Hola @charlesroddie , gracias por los comentarios.

Parece que Shell puede no ser adecuado para usted en este momento, y está bien. No es necesario que utilice Shell si no aporta valor a sus aplicaciones. Dicho esto, la especificación de Shell se basa en gran medida en los comentarios de los desarrolladores, y servir a nuestra comunidad de desarrolladores es fundamental para nuestro propósito.

En Xamarin.Forms hoy ya describe la arquitectura de su aplicación, la jerarquía de contenido, usando TabbedPage, MasterDetailPage, con pestañas y elementos de menú, y diferentes combinaciones. Esto es lo que quiero decir aquí con "arquitectura". Shell simplifica y reemplaza esos patrones (si elige usar Shell).

"Móvil" no es un error de imprenta y se utiliza de forma muy deliberada. Shell está dirigido a iOS y Android. Si tiene como destino el escritorio, no utilizará Shell. He escuchado el interés de los colaboradores sobre agregar soporte de Shell a los backends de escritorio, y esos RP serían bien recibidos. Creo que Shell está muy bien posicionado para llevar aplicaciones a cualquier plataforma y ser flexible (resistente) para adaptarse incluso a cambios radicales en los patrones de la interfaz de usuario (quién sabe qué interfaces futuras adoptarán). Por hoy, el campo de pruebas es iOS y Android.

Mientras hablamos con los desarrolladores sobre Shell, me sorprendió saber que la navegación de Shell estaba en la parte superior de la lista de características que valoraban. El enrutamiento, los enlaces profundos, la capacidad de interrumpir la navegación, describir instantáneamente la pila de actividades, pasar datos y la carga diferida de las páginas son atributos muy atractivos para los desarrolladores que resuelven los problemas que experimentan hoy.

Si su objetivo es el escritorio, no utilizará Shell ... Creo que Shell está muy bien posicionado para llevar aplicaciones a cualquier plataforma

Simplemente no quiero que Xamarin colapse por su propio peso. Hasta que Shell llegue a todas las plataformas, tiene un problema de mantenimiento, ya que entonces es una adición, no un reemplazo para otras páginas. También tiene un problema de mensajería para los desarrolladores de escritorio, en un momento en el que muchos, obviamente, buscan adoptar un marco multiplataforma.

Xamarin muestra una gran cantidad de funciones, por ejemplo, css. Esto podría amenazar todo el proyecto y espero que algunos tomadores de decisiones en la organización lo entiendan.

Simplemente no quiero que Xamarin colapse por su propio peso. Hasta que Shell llegue a todas las plataformas, tiene un problema de mantenimiento, ya que entonces es una adición, no un reemplazo para otras páginas. También tiene un problema de mensajería para los desarrolladores de escritorio, en un momento en el que muchos, obviamente, buscan adoptar un marco multiplataforma.

Xamarin muestra una gran cantidad de funciones, por ejemplo, css. Esto podría amenazar todo el proyecto y espero que algunos tomadores de decisiones en la organización lo entiendan.

Estoy de acuerdo. Si una función no es compatible con el escritorio (UWP), no nos sirve de nada. También estoy de acuerdo con CSS: parece una gran complejidad adicional y una sobrecarga de mantenimiento para una función que no me permite hacer nada que no pudiera hacer antes. Lo que necesitamos mucho más que cualquier otra cosa es solo más controles, para todas las plataformas y más capacidades para los controles existentes. Shell todavía tiene las mismas limitaciones que tiene la infraestructura de Page, ya que debe adoptarla por completo o no puede usarla en absoluto, y solo puede vivir en el nivel raíz de su aplicación. No solo eso, sino que ahora tienes dos formas de hacer lo mismo, y es complicado y confuso. Entonces, si solo quiero tener un menú flotante sin usar shell, no puedo hacer eso. Y es extremadamente limitado en la cantidad de controles a los que se asignan los elementos del shell: las pestañas, las páginas de navegación y los menús desplegables no son suficientes para nosotros. Si Xamarin Forms pudiera ofrecer la amplitud de controles que tiene un marco como UWP, expuesto como un conjunto de controles, al igual que en UWP, y sin la hinchazón inútil (por ejemplo, css), entonces estaría feliz.

Creo que ustedes plantean algunos puntos válidos, pero como alguien que mantiene una aplicación para UWP / iOS / Android y se decepcionó un poco cuando supe que Shell no era compatible con UWP, con solo un "tal vez" en el futuro. Entonces me di cuenta de que me estaba perdiendo el sentido de Shell. Es una forma muy sencilla de que alguien cree una aplicación para las dos plataformas móviles principales. Como desarrollador empresarial ... necesito UWP, esperé hasta que hubiera soporte UWP para considerar siquiera XF ... pero sospecho que muchos desarrolladores no lo necesitan ... También necesito una navegación mucho más compleja, etc. Shell proporciona.

Pero también recuerdo haber pasado mucho tiempo tratando de comenzar con la navegación y las páginas ... lo que puede llevar algún tiempo averiguarlo. Pero también estoy creando una aplicación de línea de negocios muy compleja, hay toneladas de aplicaciones simples que simplemente no necesitan ese nivel de complejidad. XF necesita evolucionar para completarse frente a cosas como Flutter, etc. También necesita seguir consiguiendo que los nuevos desarrolladores lo adopten. Y me parece que el uso de la plataforma ayudará a asegurar los recursos necesarios para mantener la plataforma.

También tengo un par de proyectos futuros en los que no necesito UWP y estoy ansioso por usar Shell en ellos porque creo que me hará mucho más rápido producirlos.

Solo he estado usando XF desde la versión 2.3 y, aunque ciertamente hay más trabajo por hacer ... la plataforma tal como existe ahora se ha estabilizado enormemente ... al menos para mí ... así que no me preocupa el mantenimiento adicional e históricamente me parece que el equipo de XF es muy consciente de la carga de mantenimiento ... así que confío en que lo tengan bajo control.

¡Gracias por la gran adición a la plataforma!

Agregar nuevas formas de hacer las cosas confundirá a los nuevos desarrolladores hasta que las formas antiguas se deprecien y se eliminen los documentos antiguos.

Flutter es mucho más simple. Sin lenguaje de marcado, todo en código. Xamarin no va a competir volviéndose más complejo y con errores. Competirá haciendo más que Flutter (más plataformas), con el mismo enfoque.

Está llegando al punto en que necesitamos un Xamarin.Core, sin incluir XAML o CSS o enlaces de propiedades, sin incluir Pages o Shells más allá de las clases base, con un enfoque en el rendimiento y la estabilidad de este Core. Si algunos desarrolladores quieren estas características a costa de aceptar la tasa actual de errores, pueden usar Xamarin.Extensions donde vivirían todas esas cosas.

Agregar nuevas formas de hacer las cosas confundirá a los nuevos desarrolladores hasta que las formas antiguas se deprecien y se eliminen los documentos antiguos.

Flutter es mucho más simple. Sin lenguaje de marcado, todo en código. Xamarin no va a competir volviéndose más complejo y con errores. Competirá haciendo más que Flutter (más plataformas), con el mismo enfoque.

Está llegando al punto en que necesitamos un Xamarin.Core, sin incluir XAML o CSS o enlaces de propiedades, sin incluir Pages o Shells más allá de las clases base, con un enfoque en el rendimiento y la estabilidad de este Core. Si algunos desarrolladores quieren estas características a costa de aceptar la tasa actual de errores, pueden usar Xamarin.Extensions donde vivirían todas esas cosas.

@charlesroddie Nada de lo que hayan hecho anteriormente lo obliga a usar XAML. XAML en Xamarin.Forms es opcional, siempre lo ha sido. Siempre hago la interfaz de usuario de las aplicaciones de Xamarin.Forms solo con código: cada "etiqueta" que ve arriba es una clase que se puede instalar y agregar al elemento primario relevante.
Si la interfaz de usuario codificada no fuera posible con Xamarin.Forms, no la usaría, ¡punto!

Re Flutter en general, es muy bueno, pero el problema es solo iOS y Android, eso tampoco funciona para mí, ya que necesito apuntarme a macOS, Windows 7 / 8.1 y Linux. ¡Nada supera a Xamarin.Forms en esto!

¿Puedo configurar la vista personalizada como una página maestra? Es muy importante incluirlo, no preferiremos solo MenuItem o páginas

¿Compatibilidad con Xamarin Mac y uwp?

¿Cómo se integraría en el proceso de navegación? Supongo que es consciente de eso, pero si toma Prism, por ejemplo, los modelos de vista son creados por un contenedor DI y se configuran automáticamente como BindingContext para la página solicitada.

También puede implementar INavigatedAware para un modelo de vista y manejar casos de uso específicos como cargar datos, habilitar / deshabilitar servicios, etc.

Quería agregar algo similar, así que mi primera suposición fue el evento OnNavigating y OnNavigated Shell, pero Current y Target no exponen un ShellItem, por lo que no es posible establecer el BindingContext por convención o desencadenar eventos de modelo de vista?

¿Alguna sugerencia para esto?

EDITAR: Seguido por # 5166.

Para los iconos de este shell, ¿es posible utilizar "Fuente de iconos" en lugar de una imagen? Es difícil cambiar el color durante el tiempo de ejecución de la imagen y también es difícil administrarlos para diferentes resoluciones en diferentes plataformas. ¿Puedo sugerir crear una clase de icono utilizando la fuente Material Design renderizada con la biblioteca SkiaSharp? La clase es relativamente fácil y hará que muchos iconos estén listos para usar en el shell.

@vincentwx estoy de acuerdo. Las fuentes de iconos son mucho más fáciles de usar y también familiares.

@vincentwx @stevehurcombe absolutamente. Estoy haciendo esto en una aplicación ahora mismo:

<ShellItem>
    <ShellContent Title="Upcoming" 
                      ContentTemplate="{DataTemplate pages:UpcomingPage}">
            <ShellContent.Icon>
                <FontImageSource Glyph="{x:Static local:IconFont.Rocket}" 
                                 FontFamily='{OnPlatform iOS="Font Awesome 5 Free", Android="fa-solid-900.ttf#Font Awesome 5 Free"}'
                                 Size="18"/>
            </ShellContent.Icon>
        </ShellContent>

        <ShellContent Title="Latest" 
                      ContentTemplate="{DataTemplate pages:LatestPage}">
            <ShellContent.Icon>
                <FontImageSource Glyph="{x:Static local:IconFont.Book}" 
                                 FontFamily='{OnPlatform iOS="Font Awesome 5 Free", Android="fa-solid-900.ttf#Font Awesome 5 Free"}'
                                 Size="18"/>
            </ShellContent.Icon>
        </ShellContent>

        <ShellContent Title="Company" 
                      ContentTemplate="{DataTemplate pages:CompanyPage}">
            <ShellContent.Icon>
                <FontImageSource Glyph="{x:Static local:IconFont.Building}" 
                                 FontFamily='{OnPlatform iOS="Font Awesome 5 Free", Android="fa-solid-900.ttf#Font Awesome 5 Free"}'
                                 Size="18"/>
            </ShellContent.Icon>
        </ShellContent>
    </ShellItem>

Usé esto para hacer una clase estática de todos los glifos: https://andreinitescu.github.io/IconFont2Code/

Hay un error con el color de iOS que debe corregirse. # 5071

¿Compatibilidad con Xamarin Mac y uwp?

No en este momento @mdonogma. Estamos acumulando interés / demanda para apoyar plataformas adicionales, pero en este momento no está en nuestra hoja de ruta.

@davidortinau Gracias por el código y el enlace.

En Android 8.0, no puedo desplazarme por la página web en el elemento WebView alojado en Shell Content. Pero funciona bien sin Xamarin Shell.

Formulario de Xamarin 4.0.0.135214-pre4

¿Existe una manera fácil de cambiar FontFamily de las pestañas inferiores y la vista del título?

@varyamereon Lo hice ayer. Extienda el Shell para poder configurar FontFamily.
Publicaré mi Shell extendido en GitHub pronto, pero:

Crea un Shell personalizado:

<Shell
    x:Class="X.Mobile.App.Features.AppShell.AppShell"

Luego crea un renderizador personalizado de Shell:

[assembly: ExportRenderer(typeof(AppShell), typeof(AppShellRenderer))]

namespace X.Mobile.App.iOS.Renderers
{
    [Preserve(AllMembers = true)]
    public class AppShellRenderer : ShellRenderer
    {
        protected override IShellItemRenderer CreateShellItemRenderer(ShellItem item)
        {
            return new CustomMenuRenderer(this)
            {
                ShellItem = item
            };
        }

Luego:

 namespace X.Mobile.App.iOS.Renderers
 {
     [Preserve(AllMembers = true)]
     public class CustomMenuRenderer : ShellItemRenderer
     {
         private SKCanvasView _skiaSharpPaintView;
         public CustomMenuRenderer(IShellContext context) : base(context)
         {
         }

public override void ViewDidLoad()
{
}           
public override void ViewWillLayoutSubviews()
{
{

Luego, para configurar la familia de fuentes: _ (no lo hagas a menudo) _

var txtAttributes = new UITextAttributes
            {
                Font = UIFont.FromName("MyriadPro-Semibold", 12.0F)
            };
            foreach (var uiTabBarItem in TabBar.Items)
            {
                uiTabBarItem.SetTitleTextAttributes(txtAttributes, UIControlState.Normal);
            }

¿Alguien que haya extendido el Shell con soporte para una ventana emergente desde abajo (hoja inferior)?

He movido mucho código de mi propio Shell antiguo al nuevo (composición, por supuesto), realmente me gusta. Incluso lo uso para una aplicación que se lanzará para prod i May :-) (depuro incluso el código Xamarin)

¿Existe soporte para vincular una lista a Shell.MenuItems? ¿O debería usar BindableLayout? A veces necesito cargar una lista de la base de datos y usarlos como menús. Tienen la misma vista, pero cargan datos diferentes según el menú que se seleccione.

¿Hay alguna forma de cambiar OffscreenPageLimit en Android cuando se usa shell? Desafortunadamente, esto es muy importante para mi aplicación y me impide seguir adelante con Shell.

¡Gracias!

Un par de solicitudes de funciones:

  1. En el nivel de shell, configure FontFamily para todos los títulos de página.
    p.ej

  2. En el nivel de shell, configure la imagen de fondo del título / navegación para todos los títulos de página / barras de navegación, etc.
    p.ej

GroupBehavior no me funciona en pre4:

<ShellItem GroupBehavior="ShowTabs" FlyoutIcon="stuff.png" Title="Discussion">...
resulta en:

xxx / Shell / Shell.xaml (14,14): Error: Posición 108: 14. No se ha encontrado ninguna propiedad, propiedad enlazable o evento para 'GroupBehavior' o un tipo que no coincida entre el valor y la propiedad.

y GroupHeaderTemplate no parece hacer nada, pero no estoy seguro de cómo se usa o habilita.

Estoy tratando de agregar / eliminar MenuItems, lo que agrega elementos con éxito a través de MenuItems.Add (elemento), pero no se muestra ningún resultado cuando se vuelve a mostrar el control flotante. ¿Es este el enfoque correcto para hacer esto?

No veo ninguna mención sobre la manipulación de MenuItems, pero el Shell es bastante inútil para mí (y estoy pensando en muchos otros, incluido @puppetSpace arriba) a menos que estos elementos se puedan mantener dinámicamente en función de la lógica de su negocio.

Estoy de acuerdo con dbwelch en que poder cambiar programáticamente el shell en el archivo cs es muy importante. No solo para los elementos del menú, sino también para ShellItems y ShellSections.

Cuando enciendo Flyout y agrego elementos de menú, obtengo un menú de hamburguesa en Android, y en iOS, si hago clic en ese lugar, funciona, sin embargo, no hay un ícono. ¿Algunas ideas?

@KyleTraynor hay un problema abierto en alguna parte para eso. Debe copiar manualmente las imágenes 3bar.png y [email protected] a su carpeta de recursos de iOS y asegurarse de que estén incluidas en el proyecto como elementos de paquete.

Se adjuntan las imágenes que encontré en la fuente:
3bar 2x
3bar

@melucas ¡ Gracias por la ayuda! Me estaba volviendo loco tratando de arreglar eso. Funciona genial.

¿Sabe cómo puedo configurar OffscreenPageLimit para Android cuando uso Shell?

Tengo páginas de pestañas superiores hechas con 4 ShellContents dentro de 1 ShellSection, y funciona muy bien en iOS, pero en Android las páginas se recargan al intercambiar entre ellas, lo que no quiero. Normalmente, con mi propia página de pestañas, podría configurar OffscreenPageLimit para solucionar este problema, pero no puedo encontrar una manera de hacerlo con Shell.

@davidortinau , ¿podríamos tener la opción de configurar la familia de fuentes en los títulos de las páginas, pestañas inferiores y superiores? En cada proyecto, tengo que crear renderizadores personalizados para ios y android para cambiar las fuentes.

Entonces, dado que, dado que no hubo respuesta a mi publicación sobre la capacidad de cambiar realmente los elementos en el Shell flotante, tal vez esta funcionalidad no esté dentro del alcance, o tal vez, con suerte, se considere un error.

No estoy seguro de cómo una aplicación seria puede usar este Shell sin esta funcionalidad. Solo las aplicaciones muy simples no requieren la capacidad de agregar / cambiar / eliminar / deshabilitar elementos en sus menús en función de a) el contexto del usuario (es decir, autenticado / no autenticado), ob) estados variables de la aplicación que lo requiera.

Solo por curiosidad @jassmith , ¿las personas que crearon la especificación están ingresadas en este foro o es solo para comentarios de los desarrolladores?

Por cierto, aparte de este elemento importante, he implementado el Shell en mi código para una aplicación y está funcionando muy bien, ¡gracias! Pero, lamentablemente, tendré que sacarlo e implementar mi propio control flotante si el Shell no tiene esta funcionalidad funcionando / implementada.

@dbwelch , un par de cosas.
Estás publicando sobre la especificación, por lo que probablemente no recibirás una respuesta como la que escribiste al abrir un nuevo número. Además, Jason ya no está trabajando en Formularios, por lo que llamarlo no tiene sentido.

En pocas palabras, presente un problema

@dbwelch @ChaseFlorell Abrí un problema aquí: https://github.com/xamarin/Xamarin.Forms/issues/5428

@davidortinau , ¿podríamos tener la opción de configurar la familia de fuentes en los títulos de las páginas, pestañas inferiores y superiores? En cada proyecto, tengo que crear renderizadores personalizados para ios y android para cambiar las fuentes.

@jamiewest ¡ Envíe una solicitud de función! ¡Gracias! https://github.com/xamarin/Xamarin.Forms/issues/new?assignees=&labels=t%2Fenhancement+%E2%9E%95&template=feature_request.md&title=%5BEnhancement%5D+YOUR+IDEA%21

¿Podría implementarse la función UseSwipeGesture?
Parece que ahora la clase ShellItem no tiene la propiedad ShellAppearance para opera.
Pero ahora en Android, las pestañas de Shell no son como TabPage (TabPage puede deslizarse de forma predeterminada).

    <ShellItem.ShellAppearance>
      <MaterialShellAppearance NavBarCollapseStyle="Full" TabBarCollapseStyle="Full" UseSwipeGesture="false">
    </ShellItem.ShellAppearance>

@jingliancui , hermano Cui, ¿hay qq o WeChat?

@juepiezhongren Hola, puedes unirte a este grupo qq para chatear conmigo 313308215

¿Veremos Shell y soporte visual para UWP sobre RTM?

Doy la bienvenida a esta idea, independientemente de lo que sea más difícil porque trabajar con páginas de navegación, páginas maestras de detalles, etc. se siente muy complicado. Tal vez esto se deba a que vengo de un entorno web (no he trabajado mucho con API nativas). Aquí me viene a la mente la personalización de la barra de navegación, los títulos de las páginas, el botón de retroceso, los elementos de la barra de herramientas, los encabezados y pies de página (ListView), etc.

Supongo que lo que estoy solicitando es que las nuevas funciones, como * Shell, se envíen teniendo en cuenta la personalización y la extensibilidad. Hay muy pocas situaciones en las que hemos estado en las que no necesitábamos hacer una serie de renderizadores, comportamientos, disparadores, etc. para realizar cosas aparentemente simples.

Independientemente de lo que se les ocurra, hagan todo lo posible para que sea más fácil para nosotros hacer que nuestras aplicaciones de Xamarin.Forms se vean tan bien como otras aplicaciones nativas. ¡Parece que esta función nos brindará una mejor plataforma de lanzamiento para aplicaciones XForms de aspecto moderno!

¿Hay un código fuente disponible para ver cómo funciona este Shell, en lugar de tener que adivinar las especificaciones? Por ejemplo, qué estilo se usa para colorear el ícono de la hamburguesa, si está disponible. Lo siento, es nuevo en C # / Xamarin, pero, si el código se pudiera ver en algún lugar, ayudaría enormemente.

@dbwelch puede navegar por el código fuente aquí mismo en GitHub. Presione "T" y escriba Shell para ver las clases asociadas. Sin embargo, puede que ese no sea el mejor punto de partida si es nuevo en C # / Xamarin. Recomiendo revisar algunas de mis muestras hasta que obtengamos más documentación:

https://github.com/davidortinau/Gastropods
https://github.com/davidortinau/ShellGallery
https://github.com/davidortinau/TheLittleThingsPlayground

Documentos: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell?tabs=android
Artículo de MSDN: https://msdn.microsoft.com/en-us/magazine/mt848639
Blog: https://blog.xamarin.com/xamarin-forms-4-0-preview/

@davidortinau gracias, pero pensé que solo estaba disponible el código publicado, ¿dónde está el código de Shell? He buscado en las ramas 4.0, Shell, otros, pero, ¡se esconde de mí! ¡Gracias!

@pauldipietro Gracias, @davidortinau De hecho, he pasado mucho tiempo en todos los enlaces (excepto LittleThings, que acabo de descargar), pero no veo cómo cambiar algo tan simple como el color del icono de la hamburguesa. Aparece como púrpura en mi aplicación, pero no tengo un color púrpura definido en ninguna parte (que puedo ver). Un poco frustrante ;-).

ACTUALIZACIÓN: Acabo de encontrar el problema y, por supuesto, es un código desagradable que existe en FinishedLaunching para agregar TintColor. DOH!

Gracias señores, agradezco la ayuda!

Tengo algunos elementos que se muestran en el panel flotante, lo cual está bien. Sin embargo, actualmente ya existe una forma de ocultar / no mostrar un elemento de Shell (no el contenido del elemento). Por ejemplo, tengo un ContentPage y solo quiero tener la navegación dentro del Shell.

<local:DetailPage />

Parece que siempre se agrega el elemento en el panel / lista desplegable. Y si no hay título, entonces tendrá una pila / marcador de posición vacío del elemento. He intentado muchas formas de ocultar el artículo y todavía no he tenido suerte. Probablemente alguien pueda ayudar o la función aún no esté disponible.

Prefacio: Soy un cajero automático novato. Tratando de no serlo.

@davidortinau Entonces, he estado tratando de aprender esta característica de Shell para agregar navegación, etc.en nuestro primer proyecto de Xamarin.Forms para nuestra empresa (¡woot!) Y estoy atascado tratando de averiguar si es posible pasar 1 o más parámetros de un ShellItem a otras partes de la aplicación a través de la nueva funcionalidad de enrutamiento. ¿Es esto algo en absoluto? ¿O debemos ceñirnos al comando usando MenuItems dentro de una colección de MenuItem en su lugar? Si debemos usar un MenuItem para pasar 1 o más valores del nivel de Flyout, parecería que ya no podemos estructurar nuestra aplicación con la jerarquía de Shell ya que estamos usando MenuItems en su lugar. ¿No perdemos eso al usar MenuItems con parámetros de comando?

¿Hay alguien que pueda intervenir en esto? Si es así, se lo agradecería mucho. Básicamente, me encantaría usar Shell, pero aún así poder etiquetar qué ShellItem seleccionó el usuario al hacer clic en uno para pasarlo a una página ContentTemplate o lo que sea apropiado, ya que muchos ShellItems navegarán a una página intermedia similar para hacer un OrderType y la selección del menú desplegable OrderDepartment antes de ir a la pantalla principal de Order con los datos adecuados para el tipo y el departamento correctos.

Además, me disculpo si este es el lugar equivocado para esto. Si es así, indíqueme el lugar correcto. ¡Gracias!

Actualizar:
Tal vez solo use MenuItems por ahora y pase un parámetro de comando a ShellViewModel para navegar con los valores correctos para la página de destino. Ahora que lo pienso, realmente no necesitaré navegar a una estructura con pestañas desde esos MenuItems que empujan a la página ContentTemplate.

También me preguntaba si podemos definir dónde se encuentran los MenuItems dentro del Flyout para que los ShellItems no aparezcan todos en la parte superior; y si un día no tenemos que definir nuestros MenuItems como parte de una colección para que puedan entremezclarse con ShellItems como:
MenuItem
ShellItem
ShellItem
MenuItem
ShellItem
MenuItem
...
Eso, o simplemente hacer que ShellItems pueda pasar parámetros en algún momento si ya no pueden.

Estoy con @anthcool y encuentro que esta es una característica extremadamente importante. No pude encontrar una manera de hacer esto y tuve que dejar de usar Shell. Solo necesita poder pasar algo a una página de contenido para saber en qué se hizo clic.

@anthcool solo readonly Stack<NavigationParameter> como una lista de pila, es decir

public class Navigation
{
    readonly Stack<NavigationParameter> _stack = new Stack<NavigationParameter>();
...
    public Stack<NavigationParameter> Parameters => _stack;
}

El NavigationParameter es:

public class NavigationParameter : NameValueCollection { }

Puede agregar parámetros antes de la inserción al navegar, por ejemplo:

    var p = new NavigationParameter { { nameof(SomePage), SomeObject } };
    Navigation.Parameters.Push(p);

Una vez que estés en la otra página, solo mira o abre el valor y verifica la clave.
Algo parecido a lo anterior. Espero que ayude.

@anthcool solo readonly Stack<NavigationParameter> como una lista de pila, es decir

public class Navigation
{
    readonly Stack<NavigationParameter> _stack = new Stack<NavigationParameter>();
...
    public Stack<NavigationParameter> Parameters => _stack;
}

El NavigationParameter es:

public class NavigationParameter : NameValueCollection { }

Puede agregar parámetros antes de la inserción al navegar, por ejemplo:

    var p = new NavigationParameter { { nameof(SomePage), SomeObject } };
    Navigation.Parameters.Push(p);

Una vez que estés en la otra página, solo mira o abre el valor y verifica la clave.
Algo parecido a lo anterior. Espero que ayude.

¡Gracias por la idea @rizamarhaban! Realmente agradezco que se haya sumado a esto. ¡Gracias! Veré esto aquí pronto. Una vez más, ¡lo agradezco!

Me decepcionó mucho saber que Shell y Visual no son compatibles con UWP.

¿Está realmente hecha esta especificación?
¿Por qué cerrar esto solo porque ahora hay una implementación de Tizen?
Tenía la impresión de que la funcionalidad de navegación aún estaba en revisión.

Todavía no hay soporte para UWP. La mayor decepción que he tenido de Xamarin.

@weitzhandler Por favor [email protected] si desea discutir esto y UWP en general. No estamos ignorando activamente la plataforma, pero Android e iOS están recibiendo la implementación inicial y las investigaciones sobre el soporte de Shell para UWP están en curso de forma activa.

@mrlacey ¡ No, no está ni cerca de terminar! Simplemente sigue cerrándose por problemas relacionados. 😄

Para todos aquellos que solicitan soporte para UWP, lo probé: https://github.com/xamarin/Xamarin.Forms/pull/6015

¿Hay alguna forma de implementar una plantilla de barra de navegación en la página de contenido?
La especificación de NavigationPage.TitleView no se aplica como antes.
Repo para referencia:
https://github.com/InquisitorJax/Xamarin-Forms-Shell

EDITAR:
Murphy ataca de nuevo, solo use Shell.TitleView en lugar de NavigationPage.TitleView :)

Hola,
En mi nuevo proyecto estoy usando Shell y CollectionView, ¡y debo decir que son geniales!
Una pregunta sobre Shell

  • hay una manera de agregar un elemento inferior fijo (ejemplo de zorro, un botón para cerrar la sesión del usuario)

Veo que es posible agregar un encabezado fijo (FlyoutHeader y FlyoutHeaderBehavior) pero no puedo encontrar ninguna información sobre el pie de página inferior
¡Gracias!

Hola,
Tengo otra pregunta sobre RegisterRoute.
Mi aplicación es bastante grande, con un número considerable de páginas, unas 30 ...
¿Es realmente la forma correcta de agregar RegisterRoute para cada uno de ellos?
Routing.RegisterRoute("blabla", typeof(BlaBlaPage)); ... ...
¿O es mejor usar el método antiguo?
var blaPage = new BlaBlaPage (); await Navigation.PushAsync (blaPage);

@matteopiccioni Recomendaría hacerlo así

Routing.RegisterRoute("blabla", typeof(BlaBlaPage));

y usando
gotoasync("blabla")

Me doy cuenta de que en este momento se siente igual, pero a medida que las funciones crezcan, será más relevante tener todas esas cosas funcionando a través del sistema Shell.

¿Es realmente la forma correcta de agregar RegisterRoute para cada uno de ellos?

Si esto se convierte en un problema, estamos buscando agregar algunas características que solo escanearán en busca de páginas o tal vez incluso algunas características de tiempo de compilación que generarán esas rutas.

El problema principal aquí es que cualquier tipo de reflexión ralentizará su aplicación, por lo que hacerlo al inicio costará

@PureWeen gracias por la respuesta
El tiempo de inicio lento es uno de los problemas más molestos en xf (para Android)
En el inicio, ¿podría agregar al enrutamiento solo el primer nivel de páginas (las páginas de shellitems) y agregar los demás solo después de que se inicie la aplicación (una especie de carga diferida de RegisterRoute)?

@matteopiccioni

Entonces, si lo haces así todo a la vez

Routing.RegisterRoute("blabla", typeof(BlaBlaPage));

está bien. Todo lo que estaba hablando es que si terminamos construyendo algo que lo haga para que los usuarios no tengan que hacerlo, tendremos que sopesarlo con el rendimiento. En este momento, Routing.RegisterRoute("blabla", typeof(BlaBlaPage)); no hace ninguna reflexión, por lo que hacerlo todo a la vez está bien.

todo lo que hace es agregar una cadena y escribir a un diccionario

@jassmith @jamesmontemagno @pierceboggan Wow se ve genial. ¿Has visto la aplicación Contactos de Google usando Pie SDK en un Google Pixel? Me encanta la UI / UX, sin barra de título y la hamburguesa integrada en la parte superior de la aplicación.

¿Se puede considerar esta sugerencia para su Shell ya que es un patrón que está usando Google, con Contactos y Mapas, y tal vez con otros?

Gracias por su tiempo y consideración,

Karl

Tenga en cuenta que todas las muestras que siguen no utilizan ShellContent con plantilla, que se analizan en otra parte de la especificación. Si no se usa correctamente ShellContents con ContentTemplate, todas las páginas se cargarán al inicio, lo que afectará negativamente el rendimiento de inicio. Estas muestras son solo para fines de aprendizaje.
Afortunadamente, usar ShellContents con ContentTemplates suele ser más conciso que no usarlos.
[...]
Un problema importante con el uso de Shell es la facilidad con la que un usuario puede terminar cargando todas las páginas al inicio de la ejecución de su aplicación. Esta gran asignación de carga anticipada puede resultar en un rendimiento de inicio bastante pobre si se necesita una gran cantidad de páginas de contenido. Para solucionar este problema, se deben emplear plantillas siempre que sea posible.

Para mí, esto suena a que nunca deberías usar el contenido directamente, sino usar plantillas. Esto tiene sentido para mí, entonces, ¿por qué apoyar el enfoque de contenido directo? (aparte de la simplicidad, pero es dejar que la gente se pegue un tiro en el pie). Parece que poder usar contenido directo es más una característica "excelente cuando se hace una demostración; de lo contrario, es horrible".

Hola,
Soy nuevo aquí. No estoy seguro de si este es el lugar adecuado para hacer preguntas; de lo contrario, indíqueme dónde preguntar:
Intenté hacer algo similar a la muestra especificada anteriormente:

  <ShellItem Title="My music" ItemsSource="{x:Bind MyMusicModels}" TabLocation="Bottom">
    <ShellItem.ItemTemplate>
      <local:MyMusicItemTemplateSelection />
    </ShellItem.ItemTemplate>
  </ShellItem>

Pero tengo los siguientes errores:

Error XLS0413 No se encontró la propiedad 'ItemsSource' en el tipo 'ShellItem'.
Error XLS0415 La propiedad adjunta 'ItemTemplate' no se encontró en el tipo 'ShellItem'.

@PureWeen Esperaba usar esta idea :).
¿Está sugiriendo que esta idea aún no se ha implementado?
Si aún no está implementado, podría estar interesado en trabajar en él.

@Elashi no lo es, pero pude ver que es una característica realmente poderosa para los escenarios MVVM

Si quieres trabajar en ello, ¿puedes crear un problema con los conceptos básicos de lo que estás pensando?

Entonces, de prueba y error ... A pesar de que tiene comentarios sobre gestos en shell 3.2 y está en TheLittlePlayground, no puedo por mi vida hacer que Gestures funcione en ANDROID con el paquete visual.

¿Me falta algo en las notas de que los gestos de Shell + solo funcionan con iphone?

@davidortinau Sé que estas son solo algunas especificaciones, y ha estado cerrada por un tiempo, pero esperaba que pudiera señalarme en la dirección correcta ya que las especificaciones señalan que la siguiente tarea está completada o en el expediente para desarrollo:

  • Agregue API para elementos de "submenú" para el GPS ala de ShellContent -> Música -> Aplicación de música abierta

Actualmente, dado que no puedo hacer que los GroupHeaders funcionen, estoy buscando reelaborar mi FlyoutMenu para clasificar en 6 grupos principales, y luego hacer que aparezca un submenú lleno de FlyoutItems que me lleve a la ruta que he predeterminado.

Mi caso de uso es que tengo más de 50 opciones para mostrar y poner eso en un estado de desplazamiento no es compatible con la interfaz de usuario, pero cada opción que se muestra es algo que necesito para permitir que mis usuarios accedan de manera eficiente sin tener que desplazarse interminablemente. La clasificación en grupos según el tema general de cada opción tiene más sentido desde el punto de vista de UI / UX.

¿Puede arrojar algo de luz sobre dónde se encuentra eso en términos de desarrollo / producción? - ¿O apuntarme en la dirección de una base de código que lo implementa para que pueda aprender? (Solo he estado con Xamarin durante 1 mes, por lo que todavía soy nuevo en algunos de los recursos disponibles).

@TheBaileyBrew

Acabo de buscar en Google este repositorio con algo que probablemente funcione para su escenario. No será Shell, pero probablemente podría usarlo en una configuración de MasterDetailPage.

https://github.com/ishrakland/ListViewWithSubListView/

Además, acaban de trasladar y actualizar gran parte de su material del curso a MSFT Learn (que estoy revisando yo mismo para llenar los vacíos). Eso se encuentra aquí: https://docs.microsoft.com/en-us/learn/browse/?products=xamarin

Intentaría repasar lo anterior. ¡Mucha suerte y bienvenido a bordo!

Hola chicos, quiero elegir un archivo o fotos de la galería o del almacenamiento externo en
xamarin forma a quien elegir archivarlo? El archivo solo tiene la extensión .PDF. Para
seleccione los dos archivos que utilizo un botón, así que por favor ayúdenme !!!

El jueves 23 de mayo de 2019 a las 19:41, Anthony Cool [email protected] escribió:

@TheBaileyBrew https://github.com/TheBaileyBrew

Acabo de buscar en Google este repositorio con algo que podría funcionar para su escenario
más probable. No será Shell, pero puede usarlo en una MasterDetailPage
configuración probablemente.

https://github.com/ishrakland/ListViewWithSubListView/

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/xamarin/Xamarin.Forms/issues/2415?email_source=notifications&email_token=AK7KSYK4N3XIVP3IHOBE2P3PW3CKJA5CNFSM4EZ4GB52YY3PNVWWK3TUL52HS4DFVREXWG43
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AK7KSYI5XKMXD7FC7HZH45LPW3CKJANCNFSM4EZ4GB5Q
.

Hola chicos, quiero agregar pestañas en función de la condición, entonces, ¿cómo puedo agregar pestañas en Shell usando C # no en Xaml y cómo agregar elementos de menú?

@TheBaileyBrew

¿Es esto lo que estás buscando?
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/flyout#flyout -display-options

@BeleShew, su pregunta probablemente sea más adecuada para stackoverflow o over en forums.xamarin.com

@PWaliaDev lo haría a través de las diversas colecciones de elementos que forman parte del shell

Shell.Items.Add (nuevo ShellItem ())
new ShellItem (). Items.add (new ShellSection ())
new ShellSection (). Items.Add (new ShellContent ())

Aunque supongo que si solucionamos este problema
https://github.com/xamarin/Xamarin.Forms/issues/5428

que se adapte a tu escenario?

@PureWeen : tengo las opciones de visualización establecidas por su enlace, pero lo que estoy luchando está más cerca de lo que @BeleShew está tratando (crear / eliminar elementos flotantes por usuario)

Arreglar # 5428 encajaría con lo que estoy buscando lograr.

Mi aplicación tiene usuarios con una multitud de roles / acceso y necesito mostrar las opciones de menú mediante programación solo a aquellos usuarios que están autorizados (no quiero que los usuarios vean lo que _ no pueden _ hacer, solo lo que pueden.

Aunque he estado jugando con esto, tratando de averiguar si es posible inspeccionar las opciones de mi menú y agregar en lugar de ocultarlo como lo hace este código (pero tendría que iterar contra todas las rutas posibles y opciones de menú que consumirían tiempo de carga:

foreach (var item in this.Items)
        {
            if (item is FlyoutItem)
            {
                var removeSections = new List<ShellSection>();
                var fi = item as FlyoutItem;
                foreach (var child in fi.Items)
                {
                    if (child.Route == "NOT_AUTHORIZED_KEY")
                        removeSections.Add(child);
                }
                foreach (var s in removeSections)
                    fi.Items.Remove(s);
            }
        }

Shell es genial en teoría pero no en términos prácticos sin estas características imprescindibles.

  1. Agregar / eliminar elementos de shell dinámicamente según la función del usuario
  2. Escenario de inicio de sesión / cierre de sesión o dos rutas de navegación separadas según las condiciones.
  3. Opcionalmente, soporte para otros marcos MVVM como Prism

No se puede utilizar Shell en aplicaciones orientadas a empresas hasta que se proporcionen las funciones 1 y 2.

@ Im-PJ ¿Por qué crees que 1 y 2 no son posibles? (bastante seguro de que lo son)

3 está en progreso y se rastrea aquí .

¿Alguien sabe si es posible obtener un evento de toque desde una pestaña de App Shell?
pregunta del foro relacionada: https://forums.xamarin.com/discussion/159748/app-shell-pop-to-root-on-tab-tap

Totalmente de acuerdo con @ Im-PJ, y no entiendo cómo estas funciones no se proporcionan específicamente. Es una de las principales razones de una herramienta como Shell. ¡Cualquiera puede crear un menú deslizable!

@dotMorten tal vez pueda hacer 1 o 2 a través de C # extenso y piratería, pero NO hay ejemplos o menciones de vincular / deshabilitar / ocultar / agregar elementos de Shell en tiempo de ejecución que pueda encontrar. Parece que las capacidades dinámicas habrían sido un objetivo principal de esta herramienta. La creación de una representación XML, junto con algunas funciones de ruta, es mínima, suficiente para ofrecer a la gente de marketing, pero no suficiente para usarla en una aplicación móvil real y con todas las funciones.

@ Im-PJ

¿puede ampliar un poco en qué se diferencian?

Agregar / eliminar elementos de shell dinámicamente según la función del usuario
Escenario de inicio de sesión / cierre de sesión

Actualmente, puede hacer un escenario de inicio de sesión / cierre de sesión utilizando una barra de pestañas u ocultando la navegación flotante si se encuentra en una página de inicio de sesión

<TabBar Route="LoggedOut">
<LoginPage>
</TabBar>

<FlyoutItem Route="LoggedIn"></FlyoutItem>
<FlyoutItem></FlyoutItem>
<FlyoutItem></FlyoutItem>
<FlyoutItem></FlyoutItem>

Si está en la página de inicio de sesión, la única forma de salir es a través del código.

Se está trabajando aquí para exponer una propiedad enlazable de IsVisible
https://github.com/xamarin/Xamarin.Forms/tree/shell_isvisible

Solo necesita un poco de refinamiento antes de crear un PR

dos rutas de navegación separadas según las condiciones.

¿Puede proporcionar ejemplos de lo que está tratando de hacer y lo que no puede hacer actualmente?

hoi1
Estoy usando Xamarin.Form Shell

Ejemplo de enlace: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/flyout

Por favor, ayúdame. ¿Cómo mostrar la barra de pestañas en la página Acerca de?

Necesito tener dos páginas de shell al mismo tiempo.
Uno para un menú flayout con página como inicio, configuración, cierre de sesión, etc.
Uno para las páginas con pestañas que deben enviarse desde casa
Por ahora tengo que usar la 'vieja manera'

Necesito tener dos páginas de shell al mismo tiempo.
Uno para un menú flayout con página como inicio, configuración, cierre de sesión, etc.
Uno para las páginas con pestañas que deben enviarse desde casa
Por ahora tengo que usar la 'vieja manera'

Si usa Tabbedpage, no puede mostrar Flyout. Quiero mostrar Flyout y Tabbar en este momento.

Puse todas las paginas en elpara que las páginas muestren la barra de pestañas, pero solo quiero tener 4 elementos en la barra de pestañas (no quiero mostrar la pestaña Más). Como hacer

<shell>
<flyoutitem route="animals" flyoutdisplayoptions="AsMultipleItems">
<shellcontent route="cats"/>
<shellcontent route="dogs"/>
<shellcontent route="monkeys"/>
<shellcontent route="elephants"/>
<shellcontent route="bears"/>
<shellcontent route="about"/>
</flyoutitem>
</shell>

Necesito tener dos páginas de shell al mismo tiempo.
Uno para un menú flayout con página como inicio, configuración, cierre de sesión, etc.
Uno para las páginas con pestañas que deben enviarse desde casa
Por ahora tengo que usar la 'vieja manera'

Si usa Tabbedpage, no puede mostrar Flyout. Quiero mostrar Flyout y Tabbar en este momento.

Puse todas las páginas para que las páginas muestren la barra de pestañas, pero solo quiero tener 4 elementos en la barra de pestañas (no quiero mostrar la pestaña Más). Como hacer

<shell>
<flyoutitem route="animals" flyoutdisplayoptions="AsMultipleItems">
<shellcontent route="cats"/>
<shellcontent route="dogs"/>
<shellcontent route="monkeys"/>
<shellcontent route="elephants"/>
<shellcontent route="bears"/>
<shellcontent route="about"/>
</flyoutitem>
</shell>

Desafortunadamente no puedo usar Shell
Todavía tengo MasterDetailPage y TabbedPage en la misma aplicación (en iOS tengo páginas con pestañas superiores usando el complemento Naxam.TopTabbedPage.Forms)
Este era mi viejo boleto

¿Fue útil esta página
0 / 5 - 0 calificaciones