<p>Xamarin.Forms.Shell-Spezifikation</p>

Erstellt am 10. Apr. 2018  ·  199Kommentare  ·  Quelle: xamarin/Xamarin.Forms

Xamarin.Forms-Shell-Spezifikationen

Machen Sie es neuen Entwicklern einfach und unkompliziert, eine vollständige App-Erfahrung zu erhalten, die richtig strukturiert ist, die richtigen Elemente verwendet, mit sehr wenig Aufwand und einem klaren Weg, um standardmäßig gut zu sein.

Shell ist an einigen Stellen eine rechthaberische API, sie setzt nicht immer jeden Wert auf einen .Default, der sich je nach laufender Plattform ändern kann. Stattdessen kann es einen Wert festlegen, der dann auf allen Plattformen respektiert wird, unabhängig vom Plattformstandard.

Hinweis: Zeichnungsspezifikation verschoben nach: # 2452

Visuelle Behandlung

Braucht Screenshots...

Shell-Hierarchie

Das Verständnis der Shell-Hierarchie kann zunächst überwältigend erscheinen. Es stellt eine komplexe Hierarchie dar und bietet leistungsstarke Mechanismen zum Minimieren der Menge an Boilerplate-Xaml, die zum Erstellen umfangreicher Hierarchien erforderlich ist.

Daher ist es beim ersten Erlernen der Shell am einfachsten, zuerst ohne die Verknüpfungen zu lernen und dann die Verknüpfungen einzuführen, um zu sehen, wie Sie die Menge an geschriebenem XAML auf einfache Weise minimieren können.

Beachten Sie, dass alle folgenden Beispiele keine ShellContents mit Vorlagen verwenden, die an anderer Stelle in der Spezifikation erläutert werden. Wenn ShellContents nicht ordnungsgemäß mit einem ContentTemplate verwendet wird, werden alle Seiten beim Start geladen, was sich negativ auf die Startleistung auswirkt. Diese Beispiele dienen nur zu Lernzwecken.

Glücklicherweise ist die Verwendung von ShellContents mit ContentTemplates normalerweise prägnanter, als sie nicht zu verwenden.

Keine Abkürzungen

Viele dieser Beispiele sehen unnötig komplex aus, und in Wirklichkeit sind sie es auch. Im nächsten Abschnitt werden diese vereinfacht.

Eine einfache One-Page-App

<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

Die obere Leiste kann vollständig ausgeblendet werden, indem auf der MainPage Shell.NavBarVisible="false" gesetzt wird. Das Flyout würde in diesem Modus auch eher spärlich aussehen und ist daher in diesem Beispiel deaktiviert.

Zweiseitige App mit unteren Registerkarten

<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

Durch Hinzufügen eines Abschnitts ShellSection zu ShellItem weitere untere Registerkarte. Die Einstellung des entsprechenden Titels und Symbols ermöglicht die Kontrolle über den Titel und das Symbol des Tab-Elements.

Zweiseitige App mit oberen und unteren Registerkarten

<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

Durch Hinzufügen eines zweiten ShellContent zu ShellSection eine obere Registerkartenleiste hinzugefügt und die Seiten können zwischen den Seiten gewechselt werden, wenn die untere Registerkarte ausgewählt wird.

Zweiseitige App mit Flyout-Navigation

<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

Das Flyout ist in diesem Beispiel wieder aktiviert. Hier kann der Benutzer über das Flyout als Vermittler zwischen den beiden Seiten wechseln. Ein Header wurde auch hinzugefügt, um gut auszusehen.

Verwenden der Abkürzungssyntax

Nachdem nun alle Ebenen der Hierarchie dargestellt und kurz erklärt wurden, ist es möglich, bei der Definition einer Hierarchie die meisten unnötigen Umhüllungen wegzulassen. Shell enthält immer nur ShellItem s, die immer nur ShellSection s enthalten, die wiederum immer nur ShellContent s enthalten. Es gibt jedoch implizite Konvertierungsoperatoren, die ein automatisches Up-Wrapping ermöglichen.

Eine einfache One-Page-App

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

Beim impliziten Umbruch wird die Seite automatisch bis zu einem ShellItem umbrochen. Es ist nicht erforderlich, alle Zwischendatenschichten auszuschreiben. Die Title und Icon aus den Page werden an alle implizit generierten Eltern gebunden.

Zweiseitige App mit unteren Registerkarten

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

Die Seiten sind jetzt implizit in ShellContent und ihre eigenen ShellSections eingeschlossen. Dies führt dazu, dass wie zuvor zwei verschiedene Registerkarten erstellt werden.

Zweiseitige App mit oberen und unteren Registerkarten

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

Zweiseitige App mit Flyout-Navigation

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

Hier reicht die implizite Verpackung bis zum Schalenartikel, sodass wir keine Verpackung selbst vornehmen müssen.

Navigationsmodell

Push-Navigation

Die gesamte Navigation basiert auf der .Navigation-Eigenschaft der Ansicht. Pushs gehen in die aktuelle ShellSection, die angezeigt wird. Dies bedeutet, dass bei einem Push-Ereignis die oberen Registerkarten verschwinden und die unteren Registerkarten bleiben.

URI-Navigation

Die Shell kann wie oben beschrieben mit der Standard-Navigationseigenschaft navigiert werden, jedoch führt die Shell einen weitaus bequemeren Navigationsmechanismus ein.

Navigations-URIs sind wie folgt formatiert:

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

Allen Elementen in der Shell-Hierarchie ist eine Route zugeordnet. Wenn die Route nicht vom Entwickler festgelegt wird, wird die Route zur Laufzeit generiert. Laufzeitgenerierte Routen sind nicht garantiert stabil über verschiedene App-Ausführungen hinweg und daher nicht für Deep-Linking geeignet.

Umgang mit der Zurück-Taste

Da Shell in der beneidenswerten Lage sein wird, keine nativen Steuerelemente verwenden zu müssen, können und sollten alle Formen des Überschreibens der Zurück-Schaltfläche unterstützt werden.

Die richtige Handhabung der Zurück-Taste muss die folgenden Funktionen unterstützen:

  • Interaktionen abfangen und stoppen
  • Ersetzen der Zurück-Taste durch etwas anderes
  • Die Zurück-Taste bei Bedarf vollständig ausblenden
  • Arbeit für Software- und Hardwaretasten

Die API muss aus Gründen der Benutzerfreundlichkeit auf Seitenebene granular sein, aber auch auf einer allgemeineren Ebene weiter oben im Stack gehandhabt werden können.

Codebeispiele und API

Proben

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

Single Page App mit Shell

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

Single Group of Tabs-App (kein Flyout)

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

Mehrere Seiten im Flyout ohne Registerkarten

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

Durchsuchbare App auf einer Seite

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

```cscharf
öffentliche Klasse MyPage : ContentPage
{
öffentliche Klasse MyPageSearchHandler : SearchHandler
{
öffentlicher MyPageHandler ()
{
SearchBoxVisibility = SearchBoxVisibility.Collapsed;
IsSearchEnabled = true;
Placeholder = "Suche mich!";
}

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
}

}

öffentliche MyPage ()
{
Shell.SetSearchHandler (dieser, neuer 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);
}

Beschreibung

Angehängte Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| SearchHandlerProperty | Angehängte Eigenschaft für die Definition einer Suchfunktion auf Seitenebene. Kann an mehreren Stellen in der Hierarchie angehängt werden. Verwendet einige der hier definierten Funktionen https://material.io/guidelines/patterns/search.html#search -in-app-search |
| ZurückButtonVerhalten | Ermöglicht das vollständige Überschreiben des Verhaltens der Zurück-Schaltfläche. Gilt für Bildschirm- und physische Zurück-Tasten. |
| Flyout-Verhalten | Definiert, wie sich das Flyout präsentieren soll. Dies kann an ShellItem s, ShellContent s oder Page s angehängt werden, um das Standardverhalten zu überschreiben. |
| NavBarVisibleProperty | Eigenschaft auf Page , um zu definieren, ob die NavBar sichtbar sein soll, wenn sie präsentiert wird |
| SetPaddingInsetsProperty | Das Setzen dieser Eigenschaft auf Page bewirkt, dass dessen Padding so eingestellt wird, dass sein Inhalt nicht unter irgendein Shell-Chrom fließt. |
| TabBarVisibleEigenschaft | Eigenschaft auf Page , um zu definieren, ob die TabBar bei der Darstellung sichtbar sein soll |
| TitleViewProperty | Eigenschaft auf Page , um TitleView zu definieren |
| ShellBackgroundColorProperty | Beschreibt die Hintergrundfarbe, die für die Chromelemente der Shell verwendet werden soll. Diese Farbe wird hinter dem Inhalt der Shell nicht ausgefüllt. |
| ShellDisabledColorProperty | Die Farbe zum Schattieren von Text/Symbolen, die deaktiviert sind |
| ShellForegroundColorProperty | Die Farbe zum Schattieren von normalem Text/Symbolen in der Shell |
| ShellTabBarBackgroundColorProperty | Überschreiben von ShellBackgroudnColor für die TabBar. Wenn nicht gesetzt, wird ShellBackgroundColor verwendet |
| ShellTabBarDisabledColorProperty | Überschreiben von ShellDisabledColor für die TabBar. Wenn nicht gesetzt, wird ShellDisabledColorProperty verwendet |
| ShellTabBarForegroundColorProperty | Überschreiben von ShellForegroundColorProperty für die TabBar. Wenn nicht gesetzt, wird ShellForegroundColorProperty verwendet |
| ShellTabBarTitleColorProperty | Überschreiben von ShellTitleColorProperty für die TabBar. Wenn nicht gesetzt, wird ShellTitleColorProperty verwendet |
| ShellTabBarUnselectedColorProperty | Überschreiben von ShellUnselectedColorProperty für die TabBar. Wenn nicht gesetzt, wird ShellUnselectedColorProperty verwendet |
| ShellTitleColorProperty | Die Farbe für den Titel der aktuellen Seite |
| ShellUnselectedColorProperty | Die Farbe für nicht ausgewählten Text/Symbole im Shell-Chrom |

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Aktueller Artikel | Das aktuell ausgewählte ShellItem |
| Aktueller Status | Der aktuelle Navigationsstatus der Shell. Das Zurückgeben dieses Zustands an GoToAsync bewirkt, dass die Shell in den Zurück-Zustand zurückkehrt. |
| FlyoutBackgroundColorProperty | Die Hintergrundfarbe des Flyout-Menüs |
| Flyout-Verhalten | Legt den Standardwert FlyoutBehavior für Shell . |
| FlyoutHeader | Das als Header des Flyouts verwendete Objekt. Wenn FlyoutHeaderTemplate nicht null ist, wird dies als BindingContext an das aufgeblasene Objekt übergeben. Wenn FlyoutHeaderTemplate null ist und FlyoutHeader vom Typ View , wird es direkt verwendet. Andernfalls wird es durch Aufrufen von ToString() und Anzeigen des Ergebnisses angezeigt. |
| FlyoutHeaderVerhalten | Legt das Verhalten von FlyoutHeader wenn das Flyout gescrollt werden muss, um Inhalte anzuzeigen. |
| FlyoutHeaderTemplate | Die zum Erstellen einer Kopfzeile für das Flyout verwendete Vorlage. |
| FlyoutIstPräsentiert | Ruft ab oder legt fest, ob das Flyout aktuell sichtbar ist |
| GroupHeaderTemplate | Das DataTemplate verwendet, um einen Gruppenkopf anzuzeigen, wenn ein ShellItem die Anzeige als Gruppe von Registerkarten im Flyout anfordert. Bei null wird keine Kopfzeile angezeigt. |
| Artikel | Der primäre Inhalt einer Shell. Elemente definieren die Liste der Elemente, die im Flyout angezeigt werden, sowie den Inhalt, der angezeigt wird, wenn ein Seitenleistenelement ausgewählt wird. |
| ItemTemplate | Das DataTemplate verwendet, um Elemente aus der Sammlung Items im Flyout anzuzeigen. Ermöglicht dem Entwickler, visuelle Elemente im Flyout zu steuern. |
| Menüelemente | Eine Sammlung von MenuItem s, die im Flyout in einem eigenen Abschnitt angezeigt werden. |
| MenuItemTemplate | Das zu verwendende DataTemplate , wenn im Flyout ein MenuItem angezeigt wird. |
| Strecke | Der Routenteil zum Adressieren dieses Elements beim Ausführen von Deep Linking. |
| RouteHost | Die Zeichenfolge, die in den Hostteil des URI eingefügt werden soll, der beim Erstellen von Deep-Links generiert wird |
| Routenschema | Die Zeichenfolge, die in den Schemateil des URI eingefügt werden soll, der beim Erstellen von Deep-Links generiert wird |

Öffentliche Methoden:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| GoToAsync | Navigieren Sie zu einem ShellNavigationState . Gibt eine Aufgabe zurück, die abgeschlossen wird, sobald die Animation abgeschlossen ist. |

Öffentliche Veranstaltungen:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Navigieren | Das Shell ist dabei, eine Navigation durchzuführen, entweder aufgrund einer Benutzerinteraktion oder des Entwicklers, der eine API aufruft. Der Entwickler kann die Navigation hier nach Möglichkeit abbrechen. |
| Navigiert | Das Shell hat ein Navigationsereignis abgeschlossen. |

ShellItemCollection

Eine Sammlung für ShellItem s

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

MenuItemCollection

Eine Sammlung für MenuItem s

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

ShellSectionCollection

Eine Sammlung für ShellSection s

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

ShellContentCollection

Eine Sammlung für ShellContent s

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

ShellNavigatingEventArgs

Ein EventArgs verwendet, um ein Navigationsereignis zu beschreiben, das gerade eintreten wird. Die ShellNavigationEventArgs können auch verwendet werden, um das Navigationsereignis abzubrechen, wenn der Entwickler dies wünscht.

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

  public ShellNavigationState Target { get; }

  public ShellNavigationSource Source { get; }

  public bool CanCancel { get; }

  public bool Cancel ();
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Strom | Der aktuelle NavigationState des Shell . Wenn Sie GoToAsync mit diesem ShellNavigationState aufrufen, wird dieses Navigationsereignis effektiv rückgängig gemacht. |
| Ziel | Der Zustand, in dem sich Shell wird, nachdem dieses Navigationsereignis abgeschlossen ist. |
| Quelle | Der Navigationstyp, der aufgetreten ist, um dieses Ereignis auszulösen. Es können mehrere Flags gesetzt sein. |
| AbbrechenAbbrechen | Ob das Navigationsereignis stornierbar ist oder nicht. Nicht alle Veranstaltungen können abgesagt werden. |

Öffentliche Methoden:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Abbrechen | Bricht das aktuelle Navigationsereignis ab. Gibt true zurück, wenn die Stornierung erfolgreich war. |

ShellNavigatedEventArgs

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

  public ShellNavigationState Current { get; }

  public ShellNavigationSource Source { get; }
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Zurück | Der vorherige NavigationState des Shell . |
| Strom | Der neue Zustand, in dem sich Shell befindet, wenn dieses Navigationsereignis abgeschlossen ist. |
| Quelle | Der Navigationstyp, der aufgetreten ist, um dieses Ereignis auszulösen. Es können mehrere Flags gesetzt sein. |

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);
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Standort | Der Uri, der den Navigationszustand des Shell | . beschreibt

Konstrukteure:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| (ungültig) | Erzeugt ein neues ShellNavigationState mit einem Null-Standort |
| (Zeichenfolge) | Erstellt ein neues ShellNavigationState wobei der Standort auf das angegebene string |
| (Uri) | Erstellt ein neues ShellNavigationState wobei der Standort auf den angegebenen 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; }
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| FlyoutIcon | Das zu verwendende Standardsymbol, wenn es im Flyout angezeigt wird. Wird standardmäßig auf Symbol gesetzt, wenn nicht festgelegt. |
| Symbol | Das Symbol, das in Teilen des Chroms angezeigt werden soll, die nicht das Flyout sind. |
| IsChecked | Wenn BaseShellItem gerade im Flyout angekreuzt ist (und daher hervorgehoben werden sollte) |
| Ist aktiviert | Wenn das BaseShellItem im Chrom auswählbar ist |
| Strecke | Entspricht der Einstellung Routing.Route |
| Titel | Der in der Benutzeroberfläche anzuzeigende Titel |

ShellGroupItem

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

  public FlyoutDisplayOptions FlyoutDisplayOptions { get; set; }
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| FlyoutDisplayOptions | Steuert, wie dieses Element und seine untergeordneten Elemente im Flyout angezeigt werden |

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);
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Aktueller Artikel | Die ausgewählten ShellSection . |
| Artikel | Das ShellSectionCollection das der primäre Inhalt eines ShellItems ist. Diese Sammlung definiert alle Registerkarten in einem ShellItem. |

Shell-Sektion

[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);
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Aktueller Artikel | Die ausgewählten ShellContent der ShellSection. |
| Artikel | Das ShellContentCollection das der Stamminhalt der ShellSection ist. |
| Stapel | Der aktuelle Push-Navigationsstapel im ShellSection. |

Methoden:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| GoToAsync | Wird von Deep-Linking verwendet, um zu einem bekannten Ort zu navigieren. Sollte in den meisten Fällen nicht direkt angerufen werden müssen. |
| GetNavigationStack | Gibt den aktuellen Navigationsstapel zurück |
| OnInsertPageBefore | Wird aufgerufen, wenn die INavigation Schnittstelle InsertPageBefore Methode aufgerufen wird |
| OnPopAsync | Wird aufgerufen, wenn die INavigation Schnittstelle PopAsync Methode aufgerufen wird |
| OnPopToRootAsync | Wird aufgerufen, wenn die INavigation Schnittstelle PopToRootAsync Methode aufgerufen wird |
| OnPushAsync | Wird aufgerufen, wenn die INavigation Schnittstelle PushAsync Methode aufgerufen wird |
| AufRemovePage | Wird aufgerufen, wenn die INavigation Schnittstelle RemovePage Methode aufgerufen wird |

ShellInhalt

[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);
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Inhalt | Der Inhalt eines ShellContents. Normalerweise ein ContentPage oder BindingContext der Page durch die ContentTemplate aufgeblasen werden |
| Inhaltsvorlage | Wird verwendet, um den Inhalt von ShellContent dynamisch aufzublasen. Die Eigenschaft Content wird nach der Inflation als BindingContext . |
| Menüelemente | Die Elemente, die im Flyout angezeigt werden sollen, wenn dieser ShellContent die präsentierte Seite ist |

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();
}

Eigenschaften:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| ClearIconHelpText | Der barrierefreie Hilfetext für das Löschsymbol |
| ClearIconNameProperty | Der Name des klaren Symbols für die Verwendung mit Bildschirmleseprogrammen |
| ClearIcon | Das angezeigte Symbol, um den Inhalt des Suchfelds zu löschen. |
| ClearPlaceholderCommandParameter | Der Parameter für ClearPlaceholderCommand |
| ClearPlacehodlerCommand | Der Befehl, der ausgeführt werden soll, wenn das ClearPlaceholder-Symbol angetippt wird |
| ClearPlaceholderEnabled | Der aktivierte Zustand des ClearPlaceholderIcon. Standard ist wahr. |
| ClearPlaceholderHelpText | Der barrierefreie Hilfetext für das klare Platzhaltersymbol |
| ClearPlaceholderIcon | Das Symbol, das an der Position ClearIcon angezeigt wird, wenn das Suchfeld leer ist. |
| ClearPlaceholderName | Der Name des klaren Platzhaltersymbols für die Verwendung mit Bildschirmleseprogrammen |
| Befehlsparameter | Der Parameter für Command |
| Befehl | Die ICommand , die ausgeführt werden sollen, wenn eine Abfrage bestätigt wird
| DisplayMemberPath | Der Name oder Pfad der Eigenschaft, die für jedes Datenelement in ItemsSource angezeigt wird. |
| IsSearchEnabled | Steuert den aktivierten Status des Suchfelds. |
| ArtikelQuelle | Eine Sammlung von Elementen, die im Vorschlagsbereich angezeigt werden sollen. |
| ItemTemplate | Eine Vorlage für die im Vorschlagsbereich angezeigten Elemente. |
| Platzhalter | Eine Zeichenfolge, die angezeigt werden soll, wenn das Suchfeld leer ist. |
| QueryIconHelpTextProperty | Der barrierefreie Hilfetext für das Abfragesymbol |
| QueryIconNameProperty | Der Name des Abfragesymbols zur Verwendung mit Bildschirmleseprogrammen |
| AbfrageIcon | Das Symbol, mit dem dem Benutzer angezeigt wird, dass die Suche verfügbar ist |
| Abfrage | Die aktuelle Zeichenfolge im Suchfeld. |
| SearchBoxSichtbarkeit | Definiert die Sichtbarkeit des Suchfelds im Chrom von Shell . |
| ZeigtErgebnisse | Bestimmt, ob Suchergebnisse bei der Texteingabe erwartet werden sollen |

Geschützte Methoden:

| API | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| OnClearPlaceholderClicked | Wird immer aufgerufen, wenn das ClearPlaceholder-Symbol gedrückt wurde. |
| OnItemSelected | Wird aufgerufen, wenn ein Suchergebnis vom Benutzer gedrückt wird |
| OnQueryConfirmed | Wird aufgerufen, wenn der Benutzer die Eingabetaste gedrückt hat oder seine Eingabe im Suchfeld bestätigt. |
| OnQueryChanged | Wird aufgerufen, wenn Query geändert wird. |

SearchBoxSichtbarkeit

public enum SearchBoxVisiblity
{
  Hidden,
  Collapsable,
  Expanded
}

| Wert | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Versteckt | Das Suchfeld ist nicht sichtbar oder zugänglich. |
| Zusammenklappbar | Das Suchfeld wird ausgeblendet, bis der Benutzer eine Aktion durchführt, um es anzuzeigen. |
| Erweitert | Das Suchfeld ist als vollständig erweiterter Eintrag sichtbar. |

ZurückButtonVerhalten

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 | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| IconOverride | Ändert das Symbol für die Zurück-Schaltfläche. |
| TextOverride | Ändert den verwendeten Text, um die Rückwärtsnavigation anzuzeigen, wenn Text verwendet wird. |
| Befehl | Stellt einen Ersatzbefehl bereit, der aufgerufen wird, wenn die Zurück-Taste gedrückt wird. |
| Befehlsparameter | Der mit Command | . verwendete Befehlsparameter

FlyoutDisplayOptions

Legt fest, wie ShellGroupItem im FlyoutMenu angezeigt werden soll.

  public enum FlyoutDisplayOptions
  {
    AsSingleItem,
    AsMultipleItems,
  }

| Wert | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| AsSingleItem | Das ShellGroupItem wird als einzelner Eintrag im Flyout sichtbar. |
| AsMultipleItems | Die ShellGroupItem werden als Gruppe von Elementen angezeigt, eines für jedes Kind im Flyout. |

FlyoutHeaderVerhalten

Steuert das Verhalten des FlyoutHeader beim Scrollen.

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

| Wert | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Standard | Standardverhalten der Plattform. |
| Behoben | Kopfzeile bleibt jederzeit sichtbar und unverändert |
| Scrollen | Die Kopfzeile wird aus der Ansicht gescrollt, während der Benutzer das Menü scrollt |
| CollapseOnScroll | Die Kopfzeile wird nur auf den Titel reduziert, wenn der Benutzer scrollt |

Flyout-Verhalten

public enum FlyoutBehavior
{
  Disabled,
  Flyout,
  Locked
}

| Wert | Beschreibung |
| ------------| -------------------------------------------------- --------------------------------------------------------|
| Deaktiviert | Das Flyout kann vom Benutzer nicht aufgerufen werden. |
| Flyout | Das Flyout funktioniert wie ein normales Flyout, das vom Benutzer geöffnet/geschlossen werden kann. |
| Gesperrt | Das Flyout ist gesperrt und kann vom Benutzer nicht geschlossen werden, es überlagert keine Inhalte. |

DataTemplateExtension

Diese Erweiterung konvertiert einen Typ schnell in eine ControlTemplate. Dies ist in Fällen nützlich, in denen die Vorlage ansonsten als . angegeben würde

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

Dies kann dann auf verdichtet werden

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

Krimskrams

Was passiert, wenn Sie eine Registerkarte in Flyout auswählen, auf die verschoben wurde?

Dies entspricht dem Fokussieren der Registerkarte und dem Aufrufen von PopToRoot darauf.

Was passiert, wenn ich ShellItems wechsle und es Elemente auf dem Backstack eines ShellContents des alten ShellItems gibt?

Wenn das alte ShellItem als Vorlage verwendet wird, geht der Backstack verloren. Wenn das ShellItem kein Template hat, bleibt der BackStack intakt und beim Zurückwechseln zum alten ShellItem wird der Backstack richtig wiedergegeben. Das Zurückschalten kann den Backstack jedoch löschen, wie in der obigen Antwort angegeben.

Effizientes Laden von Seiten

Ein Hauptproblem bei der Verwendung der Shell ist die Leichtigkeit, mit der ein Benutzer beim Start seiner Anwendungsausführung alle Seiten laden kann. Diese große Frontloading-Zuweisung kann zu einer ziemlich schlechten Startleistung führen, wenn eine große Anzahl von Inhaltsseiten benötigt wird. Um dies zu beheben, sollte nach Möglichkeit Templating verwendet werden.

Shell-Inhalte mit Vorlagen

Das Erstellen von Vorlagen für Shell-Tab-Elemente ist die granularste Form der verfügbaren Vorlagen, glücklicherweise auch die einfachste. Nehmen Sie die folgende Schale.

<?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>

Wenn diese Shell geladen wird, werden alle 9 Seiten gleichzeitig aufgeblasen. Dies liegt daran, dass keine Vorlagen verwendet werden. Um grundlegendes Templating zu verwenden, können wir dies umwandeln in:

<?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>

Seiten werden jetzt nur noch bei Bedarf geladen und können bei Bedarf auch wieder entladen werden. Bei Bedarf können die ShellItems selbst auch mit einer Sammlung und einem DataTemplateSelector als Template erstellt werden, was verhindert, dass selbst die ShellContents eifrig geladen werden müssen, dies ist jedoch weitgehend unnötig und das Templating von ShellItem ist für Shells nützlicher, die ShellItems mit einer großen Anzahl von ansonsten ähnlichen Registerkarten haben . Das Erstellen von Vorlagen für den ShellContent sollte der Schlüsselbereich sein, um Vorlagen für Leistungsprobleme bereitzustellen.

Rekonstruktion der Google Play Store-Benutzeroberfläche

Bitte beachten Sie, dass dies keine Demo des besten Wegs zum Programmieren einer Anwendung ist, sondern wirklich das prägnanteste Format, um die Benutzeroberfläche für GPS zusammenzufügen. Es wird auch nicht versucht, die relevanten Seiten mithilfe von ViewModels und DataTemplateSelector zu virtualisieren. Dies bedeutet, dass dies eine ziemlich schlechte Leistung wäre, da alle Seiten beim Start der App geladen würden. Leser wird gewarnt.

Es wird davon ausgegangen, dass der gesamte Seiteninhalt richtig funktioniert, dies dient nur dazu, eine allgemeine Vorstellung von Chrome zu erhalten.

Shell.xaml

Eine ordnungsgemäße Implementierung davon würde ShellItems für jede Seite verwenden und die ItemsSource und ItemTemplate festlegen. Dies würde es ermöglichen, dass jede Seite nur geladen wird, wenn sie benötigt wird, und entladen wird, wenn sie nicht mehr benötigt wird.

<?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>

Die Shop-Seiten

<?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>

Und um die Suchleiste hinzuzufügen.

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 ());
  }  
}

Und so weiter und so weiter die Farben und den Inhalt richtig einstellen.

Für Seiten wie die Einstellungsseite, auf denen das Flyout nicht zugänglich sein soll, bis die Zurück-Schaltfläche gedrückt wird:

<?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>

MACHEN

  • [x] API für Suchfeld hinzufügen
  • [x] API für ContentSafeArea-Handling hinzufügen
  • [x] API für schwebendes Menü hinzufügen
  • [x] API für Fenstermenüelemente hinzufügen
  • [x] API für Snackbar hinzufügen
  • [x] API für Navigationsunterbrechung hinzufügen
  • [x] API für unteres Blatt hinzufügen
  • [x] API zu Position FAB hinzufügen
  • [x] Geschichten hinzufügen, um die Navigationsideen klarer zu machen (teilweise fertig)
  • [x] API im LeftBarButton-Stil hinzufügen
  • [x] Mechanismus zum Abrufen von Back Stack von ShellContent hinzufügen
  • [x] API zum Ändern der Farbe des Menübands basierend auf der ausgewählten Registerkarte hinzufügen
  • [x] Optionale Vorschlagsunterstützung für SearchHandler hinzufügen
  • [x] Unterstützung für die Konfiguration der immer erweiterten Suchleiste im Vergleich zur Suchleiste als Symbol hinzugefügt
  • [x] API zum Abrufen der Seite "Aktuell" aus der MaterialShell-Klasse hinzufügen. Wird für einige Navigationsszenarien benötigt.
  • [x] API zum Speichern von "States" im Backstack hinzufügen
  • [x] Fügen Sie eine API hinzu, um das Herauskommen von Flyouts zu blockieren
  • [x] API für "Untermenü"-Elemente für ShellContents ala GPS hinzufügen -> Musik -> Musik-App öffnen
  • [x] API für CancelPlaceholder-Befehl und -Symbol hinzufügen (wird normalerweise für das Mikrofonsymbol für die Sprachsuche verwendet)
  • [x] Segue-API
  • [x] Finden Sie heraus, was mit INavigation zu tun ist
  • [ ] Erweitern Sie die Bottom Sheet API, um den Funktionen von Google Maps zu entsprechen
  • [x] API zur Handhabung der Flyout-Präsentation
  • [ ] API zum Deaktivieren der Flyout-Geste bei Bedarf
  • [ ] Große Titel-API
  • [ ] Übergangs-API

Themen

ISearchHandler [BEHOBEN]

Es gibt eine Menge an dieser Schnittstelle, und schlimmer noch, sie wird wahrscheinlich im Laufe der Zeit erweitert werden müssen. Daher liegt es nahe, dass es sich eher um eine abstrakte Basisklasse handeln sollte, die der Benutzer implementieren kann. Dieses Unglück bedeutet noch eine weitere Objektzuordnung. Es behält jedoch die Flexibilität in der Zukunft. Es ist wahrscheinlich, dass diese Änderung eintreten wird.

Schwebendes Menü

Die Anhangs-API ist etwas schwerfällig und für Benutzer möglicherweise zu verwirrend. Schlimmer noch, es kann nicht allen Plattformen sehr gut zugeordnet werden, um sicherzustellen, dass der Anhang mit Animationen funktioniert. Es ist mehr Arbeit erforderlich, um diese API zu validieren.

shell enhancement ➕

Hilfreichster Kommentar

Leute, gestern hatten Jason und ich eine Diskussion darüber, wie wir diese Spezifikation verbessern können und wir werden ein großes Update durchführen, wir teilen dies in verschiedene Themen auf.

Alle 199 Kommentare

Lassen Sie uns dieses Gespräch in Schwung bringen, denn wir müssen wirklich von Ihnen, unserer Entwickler-Community, hören!

ZUERST , danke Mühe , dies zu erfassen und einen Vorschlag zu

Ich werde einige meiner Gedanken teilen, einige dumme Fragen stellen und einige hoffentlich nicht zu führende Fragen stellen. Als Programmmanager für Xamarin.Forms muss ich oft Fragen so stellen, dass es klingt, als hätte ich keine Ahnung (manchmal habe ich keine), aber in Wirklichkeit muss ich nur Dinge von DIR hören, ohne Worte in den Mund legen.

Es gibt Dinge, die mir an diesem Vorschlag gefallen, weil ich sehe, wie sie einige der Probleme angehen könnten, über die ich mit vielen, vielen von Ihnen gesprochen habe, und wir arbeiten daran, sie zu lösen.

Ich habe auch Vorbehalte.

Ich beginne hier mit ein paar allgemeinen Gedankengängen über das Shell-Konzept und die Entwicklererfahrung.

App-Erfahrung

um eine vollständige App-Erfahrung zu erhalten, die richtig strukturiert ist, die richtigen Elemente verwendet, mit sehr wenig Aufwand und einem klaren Weg, standardmäßig gut zu sein.

Wenn ich diesen Ansatz verwende, um meine Anwendung auf der obersten Ebene zu beschreiben, erhalte ich:

  • eine App, die auf jeder Plattform gleich aussieht
  • Materialdesign (in diesem Fall) Muster standardmäßig aktiviert
  • die neuesten Navigationsmuster mit Konfiguration aktiviert
  • Ich muss nicht arbeiten, um den Eintrag oder die Schaltfläche so anzupassen, dass sie auf iOS und Android und UWP gleich aussieht?

Ist das genau? Andere Vorteile, die ich hervorheben sollte?

Statt App ich MaterialShell . Ich muss ein neues Anwendungsparadigma auf höchster Ebene erlernen/anwenden, um davon zu profitieren?

Sobald ich in meiner App bin, bin ich wieder in ContentPage Land, richtig? Aber alle meine Button s und Entry s sind materiell und hübsch. Kann ich trotzdem OnPlatform und dergleichen vom Aussehen (oder Verhalten) abweichen, um auf einer anderen Plattform anders zu sein?

Wie sieht mein Migrationspfad von einer vorhandenen App zur Verwendung dieser "Shell" aus? Ich stelle das neue MaterialShell , beschreibe, wie meine App strukturiert und aussehen soll, und führe sie einfach aus, um die neue Güte zu sehen.

Anpassen

Welche Optionen habe ich, wenn mir das Aussehen der Flyout oder der Menüelemente gefällt, ich sie aber an meine Designer-Kompositionen anpassen muss? An welchem ​​Punkt sage ich "Ugh, ich hätte das alles selbst ausführen sollen" und verschiebe, was ich habe, in eine standardmäßige Xamarin.Forms-App-Struktur?

Wenn ich die MaterialShell komplett aufgeben muss, verliere ich all diese Styling-Güten und bin wieder da, wo ich angefangen habe (wie heute) mit einem Entry , das zwischen iOS und Android und UWP ganz anders aussieht ? Ich möchte nicht.

Es gibt einen Wendepunkt, den ich erwarte. Nachdem ich diesen Ansatz verwendet habe, um schnell loszulegen, werde ich auf einige Einschränkungen stoßen und muss meine Optionen erkunden. Was sind das und wann bin ich besser dran, MaterialShell ?

Das Problem

Ich schließe diesen ersten Kommentar mit ein paar Fragen an alle, die es lesen.

  • Ist das Problem, das dieser Vorschlag zu lösen versucht, wohldefiniert?
  • Ist es ein Problem, das Sie teilen?
  • Wenn Sie diese Spezifikation lesen, welche Probleme, mit denen Sie bei früheren Projekten konfrontiert waren, glauben Sie, dass dies für Sie gelöst werden könnte?

Wenn möglich würden Screenshots/Designbilder noch besser machen.

Schau dir auch das an:

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

@jassmith Es wäre toll gewesen, wenn die ganze Idee als Bilder präsentiert würde. Ein großes Lob an die Mühe, die Spezifikationen zu erstellen. Meine Fragen sind möglicherweise nicht richtig.

Meine Fragen sind

  • Tablet-Unterstützung, Reaktionsfähigkeit der App, die sich an unterschiedliche Layouts anpasst, wird nicht behandelt.
  • Wird die Migration vom aktuellen Modell zum neuen Modell eine Herausforderung sein? Aus der Perspektive der App-Entwickler und der Mitwirkenden von Xamarin Forms.
  • Ich stimme zu, dass die meisten Apps eine einzige Benutzeroberfläche benötigen (da die Menge an benutzerdefinierten Renderern, die wir irgendwann schreiben müssen, um dieselben UI-Konzepte zu erreichen), ohne Berücksichtigung der Plattformspezifika, wird die neue Richtung alle vorhandenen Funktionen entfernen, ebenso wie werden wir weiterhin Xamarin.Forms entwickeln? Apps mit plattformspezifischer Benutzeroberfläche oder werden alle zu neuen Standards gezwungen.
  • Gibt es in MaterialShell noch Renderer-Konzepte?
  • Können wir tatsächlich sagen, dass wir in iOS möchten, dass dies auf diese Weise gerendert wird? Flutter hat Cupertino Styles (Apple UI), die in Android funktioniert, und Android UI, die in iOS funktioniert. In welche Richtung wird sich Xamarin Forms bewegen. Werden Entwickler über die Fähigkeiten verfügen, die Flatter jetzt bietet?

Wird dies auch etwas Ähnliches wie das TextInputLayout beinhalten, um schwebende Labels/Platzhalter sowie Fehlermeldungen zu unterstützen? Wenn ja, dann denke ich, dass Binding sollte, um 'ValidateOnDataErrors' ähnlich wie wpf einzuschließen.

Sehen Sie meine Umsetzung davon hier
https://github.com/XamFormsExtended/Xfx.Controls/blob/develop/src/Xfx.Controls/XfxBinding.cs

Außerdem frage ich mich, ob MaterialShell Shell erweitern sollte, damit man eine HumanInterfaceShell für das iOS-Look and Feel erstellen könnte.

@ChaseFlorell das sollte auch mein Kommentar sein. Das Material ist großartig, aber es ist eine andere Sache, wenn wir unsere eigenen Shells schreiben wollen, um bestimmten UI-Anforderungen gerecht zu werden.

@davidortinau , @jassmith ,

Vielen Dank für die Zusammenstellung dieser Spezifikation und die Erlaubnis, Feedback zu geben.

Ist das Problem, das dieser Vorschlag zu lösen versucht, wohldefiniert?

Jawohl. Das Navigationssystem ist nicht vollständig in Xamarin Forms entwickelt, daher gibt es ein offenes Problem, wie es abgeschlossen oder vollständig umgangen werden kann.

Ist es ein Problem, das Sie teilen?

Jawohl.

Wenn Sie diese Spezifikation lesen, welche Probleme, mit denen Sie bei früheren Projekten konfrontiert waren, glauben Sie, dass dies für Sie gelöst werden könnte?

Ich werde mit dieser Frage antworten, indem ich sage, dass ich nicht glaube, dass es Probleme lösen wird. Unsere besonderen Probleme sind, dass das aktuelle Navigationssystem zu starr ist, nicht dass es nicht starr genug ist. Das klarste Beispiel für uns ist die TabbedPage. Es gibt keine TabbedView-Ansicht. Wenn wir also Tabs in unserer App haben möchten, müssen wir TabbedPage verwenden. Daher muss der gesamte Bildschirm von der TabbedPage eingenommen werden und wir können keinen Platz für eigene Schaltflächen oder andere Steuerelemente verwenden, die wir möglicherweise auf dem Bildschirm platzieren möchten. Meine Empfehlung wäre gewesen, mehr Funktionalität _aus_ Pages und nach unten in Views zu verschieben, anstatt Funktionalität in Pages auf eine noch höhere Ebene zu verschieben.

Dinge wie FloatingMenu und FlyoutBehavior machen mir Angst, weil sie implizieren, dass die Navigation im Xamarin.Forms-System weiter hartcodiert wird und den Softwareentwicklern weitere Kontrolle entzogen wird. Ich sehe einen gewissen Wert in einem standardisierten Ansatz, aber er wird definitiv seinen Preis haben.

Wir haben schon immer mit anderen XAML-basierten Technologien wie Silverlight, WPF und UWP gearbeitet. Bei diesen Technologien haben wir einen viel offeneren Ansatz, bei dem wir mehr darüber definieren können, wie die Navigation funktioniert. Vor kurzem haben wir einen UI/UX-Berater engagiert. Er war sich der Macken von XF nicht bewusst. Wir haben ihn nur gebeten, uns einige Bildschirme zu bauen, die auf der Funktionalität unserer Software basieren. Große Teile dessen, was er empfiehlt, konnten nicht implementiert werden, weil er beispielsweise kein TabbedView hatte. Ich befürchte, dass dieses Framework die Umsetzung der Designs, die uns von UX/UI-Designern vorgegeben werden, tatsächlich erschwert, anstatt die Navigation zu erleichtern.

Die andere Sache, die ich sagen würde, ist, dass dieses Framework auf anderen XAML-Plattformen beispiellos aussieht, und ich würde sagen, dass die Priorität auf der Bereitstellung von Standardisierung über die Plattformen liegen sollte, anstatt neue Frameworks bereitzustellen, mit denen die anderen Plattformen nicht kompatibel sind. Wir entwickeln derzeit für drei Plattformen: Silverlight, Xamarin.Forms und WPF. Was wir brauchen, ist eine Standardisierung über diese Plattformen hinweg, um weniger Abweichungen zu erzeugen, nicht mehr.

@dylanberry ,

es ist eine andere Sache, wenn wir unsere eigenen Shells schreiben wollen, um bestimmten UI-Anforderungen gerecht zu werden.

Jawohl. Dies ist meine Sorge. Jede App hat ihre eigenen speziellen Anwendungsfälle, und eine größere Starrheit wird es wahrscheinlich schwieriger machen – nicht einfacher, diese zu implementieren.

Es gibt auch dieses Anliegen: https://github.com/xamarin/Xamarin.Forms/issues/2452#issuecomment -380991817

Ich werde das oben Gesagte wiederholen und fragen, wie Gesten und Zeiger auf Formprimitiven funktionieren.

Ein allgemeiner Kommentar ist, dass für jede Codezeile, die einem System hinzugefügt wird, 3+ die Wahrscheinlichkeit besteht, dass fehlerhafter Code hinzugefügt wird. Es gibt bereits viele Fehler in Xamarin Forms, die behoben werden müssen. Mehr Code bedeutet, dass die Wahrscheinlichkeit, dass Fehler hinzugefügt werden, exponentiell steigt. Es wird mehr Fehler geben. Ich bin der Meinung, dass das XF-Team daran arbeiten sollte, die Größe der Codebasis zu reduzieren, anstatt sie zu vergrößern. Das Verringern der Codebasis ist die einzige Möglichkeit, die Wahrscheinlichkeit des Auftretens von Fehlern zu verringern.

Warum etwas Neues erfinden, anstatt bestehende Fehler zu beheben und zuerst sicherzustellen, dass alles grundsolide ist?

Für mich wurde es angesprochen, aber die Navigation ist der größte Stolperstein in Xamarin Forms und hat mir in den letzten drei Jahren den meisten Kummer bereitet.

Die Navigation ist nicht auf allen drei Plattformen konsistent, wobei das MasterDetail-Muster viele Probleme mit dem Hamburger verursacht, der Sie zwingt, Seiten modal zu verschieben in MD).

  • Idealerweise sollten Sie sich in vielen Fällen abmelden und den Inhalt der Navigationsleiste mit Ihrer eigenen ContentView überschreiben können. PlatformSpecifics war ursprünglich als etwas gedacht, das die Positionierung von Toolbaritems ermöglicht hätte (vor langer Zeit, als ich mit Bryan sprach), aber es stellte sich heraus, dass es von begrenztem Nutzen war.

  • Möglichkeit zum Überschreiben von Framework-Elementen wie Animationen mit Popup-Seiten

Vieles von dem, was vorgeschlagen wird, scheint sehr nützlich zu sein. Solange Sie nur die Material Shell auf bestimmten Seiten verwenden können und es nicht App-weit ist, ist der Code wirklich nützlich. Es ist sicherlich etwas, das wir verwenden würden, da ich derzeit oft "Es ist eine Einschränkung von Xamarin Forms" zu unserem UX-Mitarbeiter sage (wie ich es in meiner vorherigen Rolle getan habe). Ich wage es zu sagen, wir sollten das Feedback aus einer UX-Perspektive erhalten, die zuvor Forms-Apps gestaltet haben. Es sollte wie XamlC opt-in sein.

Beim Namen bin ich mir allerdings nicht sicher, FlexShell würde mehr Sinn machen...aber wir haben jetzt Flexbox (auch wenn wir nie danach gefragt haben...sorry David, konnte mir nicht helfen 😄)

Würde dies auch bedeuten, dass Themen tot sind? habe sie sowieso nie benutzt.

@mackayn

Es ist sicherlich etwas, das wir verwenden würden, da ich derzeit oft "Es ist eine Einschränkung von Xamarin Forms" zu unserem UX-Mitarbeiter sage (wie ich es in meiner vorherigen Rolle getan habe).

OK, aber wäre es nicht sinnvoller, die aktuelle Implementierung zu korrigieren oder zu verbessern, anstatt eine komplett neue zu erstellen, die auch mit Fehlern und Einschränkungen verbunden sein wird? Da steht direkt:

MaterialShell ist punktuell eine rechthaberische API"

Im Ernst, in wie viele verschiedene Richtungen kann Xamarin Forms gehen? Das XF-Team ist kaum in der Lage, die aktuelle XF-Implementierung zumindest für Android und iOS zu reparieren, und jetzt das? Wie sieht es mit der Fehlerbehebung, der Korrektur der XAML-Vorschau und der Leistung aus?

Es wurde ein Ticket von jemandem mit einem Vorschlag eröffnet, einfache, aber sehr nützliche Unterstützung für plattformübergreifende Solid- und Farbverlaufspinsel @jassmith antwortete, dass dies problematisch wäre. Aber jetzt schlägt dieses Ticket dasselbe vor.... Wie ist das nicht mehr problematisch? Stelle dir das vor

@opcodewriter

Ja, ich habe im letzten Jahr gesagt, dass es eine seltsame Navigation gibt, die zum Beispiel das Prism-Team zurückhält und es nie in der Lage war, Probleme zu lösen.

Ich versuche vorerst nur konstruktives Feedback zu geben. Xamarin Forms befindet sich an einem kritischen Punkt in seiner Entwicklung. Diese API könnte viele der Schwachstellen beheben, wenn sie auf flexible Weise und nicht als App-weiter Ansatz implementiert wird.

@jassmith bedeutet dies, dass XF den Flutter-Ansatz (mit einer Rendering-Engine anstelle von nativen Steuerelementen) für die Shell verwendet?

Leute, gestern hatten Jason und ich eine Diskussion darüber, wie wir diese Spezifikation verbessern können und wir werden ein großes Update durchführen, wir teilen dies in verschiedene Themen auf.

Ich möchte einige der oben genannten Ansichten wiederholen: Bitte verbessern wir einfach das, was wir haben, es sei denn, Sie haben natürlich unbegrenzte Ressourcen, dann machen Sie es

Es werden noch so viele Dinge ausgelassen: ListView reparieren (kaum zu glauben, dass dies immer noch nicht richtig funktioniert), Steuerelemente wie CheckBox, RadioButton implementieren, Pinselunterstützung implementieren (SolidColorBrush, GradientBrush), Möglichkeit, ein Popup basierend auf einer Seite anzuzeigen oder ContentView, Beheben von Fehlern (siehe kürzlich gemeldete Fehler zu transparenten Ansichten), Leistung, Tools und vieles mehr....

Warum willst du etwas Neues anfangen?????

@TonyHenrique Ja, Bilder wären toll. Ich bin leider kein Künstler und besitze keine Rechte an den Bildern, die ich für meine eigene Referenz verwende. Ich hoffe, dass ein Mitglied des Designteams Zeit hat, mir zu helfen, die richtigen Bilder für die Spezifikation zu erstellen.

@muhaym

  • Tablet-Unterstützung. Es soll sicherstellen, dass das Layout an Tablets angepasst ist. Dies wird natürlich nicht Fälle für das Layouten innerhalb Ihrer Inhaltsseiten abdecken, das wäre eine andere Funktion. Weitgehend würde ich das mit dem neuen VSM handhaben.
  • Meistens einfach nur Ihre ContentPages an die richtige Stelle setzen und an die neuen Navigationskonzepte anpassen. Ich werde nicht sagen, dass es immer trivial sein wird, aber es sollte auch nicht schwächen.
  • Absolut keine Funktionen entfernen. Tatsächlich arbeite ich daran, die Spezifikation zu aktualisieren, um eine Shell-Basisklasse aufzunehmen, die einige der Funktionen von MaterialShell vermisst, aber ansonsten eine plattformspezifische UI-Version von Shell ist.
  • Jawohl. Das Hinzufügen einer Zeichnung ändert nur den Renderer, den Sie zu etwas bekommen, das weiß, wie eine Zeichnung behandelt wird.
  • Jawohl. Sie können auf jeder Hierarchieebene austauschen, welcher Renderer verwendet wird. Die Renderer werden lediglich geändert, indem Vorlagen mit speziellen Schlüsseln in Ressourcenwörterbüchern gesetzt werden. Sie können diese Vorlagen beliebig ändern oder deaktivieren, indem Sie sie auf null setzen.

@ChaseFlorell nein, aber ich beifügen möchten. Was die Sache Shell vs. MaterialShell betrifft, habe ich das oben angesprochen. Schritt 1 stellte sicher, dass MaterialShell sinnvoll ist, dann ist es Schritt 2, es auf eine Basisklasse aufzuteilen.

@dylanberry die Basisklasse

@RichiCoder1- Gesten werden hier eingefügt, aber das Wesentliche ist, dass die Ansichten mit Unterbereichsgesten als Teil der CommandableSpan-API kommen und erweitert werden, um auch Zeichnungen mit Gesten zu unterstützen. Im Allgemeinen wird jedoch empfohlen, KEINE Gesten zu verwenden und die Eingaben von den nativen Backends verarbeiten zu lassen. Dies hat zu diesem Zeitpunkt nichts mit der MaterialShell-Spezifikation zu tun und gehört zur Zeichnungsspezifikation, auf die ich gerne näher eingehen möchte. Der lange und kurze Grund ist der Grund, warum DrawingTemplate eine Sache ist, dass wir ein SliderDrawingTemplate einfügen können, das mehrere Drawings enthält, aus denen der Renderer weiß, wie er einen Slider zusammensetzt, und ermöglicht, dass die Eingabebehandlung weiterhin im nativen Backend behandelt wird. Dies bedeutet nicht, dass Sie dazu gezwungen wären, es wäre einfach eine optionale Sache, den Renderer so schnell wie möglich zu machen.

@mackayn eine Transitions/Segue-API kommt und sollte bald hier landen. Ich arbeite noch an einigen meiner ursprünglichen Vorschlagsnamen. Es wird sicherlich etwas sein, das in Phasen kommt, wobei sich nur Seitenübergänge in Phase 1 befinden. Dadurch können Sie jedoch Framework-Animationen überschreiben. Was das Opt-in angeht. Die Shell muss das Stammverzeichnis Ihrer Anwendung sein und kann nichts anderes als die von TemplatedPage verschachteln. Das heißt, das Thema der internen Kontrolle liegt zu 100% in Ihrer Kontrolle. Es ist kaum mehr als ein magischer Schalter zum Ein- und Ausschalten der neuen Vorlagen und Sie können diesen Schalter auf die gleiche Weise steuern wie wir. Auf diese Weise können Sie das Theming auf der Seite, im Layout oder sogar auf der Steuerungsebene aktivieren und deaktivieren.

@encrypt0r nicht genau. Betrachten Sie es als Hybrid. Es wird das Rendern ermöglichen, aber unter der Haube sind alle plattformspezifischen Steuerelemente nur mit Zeichencode versehen. Es gibt jedoch eine Fluchtluke zu Skia, die leicht hinzugefügt werden könnte (obwohl ich bezweifle, dass sie in die Nähe einer v1 kommt).

@opcodewriter ListView2 (offensichtlich wird es nicht wirklich so genannt) ist dieses Jahr endlich auf der Roadmap. Warum ein neues ListView? Nun, die ursprüngliche API führt zu einer nahezu unbegrenzten Anzahl von Fehlern und Problemen, die wir nicht wirklich effektiv beheben können, ohne die Abwärtskompatibilität vollständig zu unterbrechen. Dinge wie Cell/ViewCell und ItemsViewund die TemplatedItemsList, obwohl sie gut für das funktionierten, was sie für eine 1.0 gedacht waren, sind sie bei weitem nicht in der Lage, was sie für die moderne Verwendung der API sein müssen.

Leider kann ich mir keine Möglichkeit vorstellen, dies innerhalb des ListView-Typs selbst zu lösen, und ich glaube, die Community war auch nicht in der Lage, dies zu tun. Die beste Option im Moment ist, ListView so zu belassen, wie es ist, und dann etwas viel schlankeres zu machen, mit weniger Aufwand, weniger Buchhaltung, weniger seltsamen Typen, die nicht existieren müssen, und darauf vertrauen, dass die Zielframeworks das tun, was sie am besten können.

Das einfache Entfernen der alten Recyclingstrategie, die eine große Backcompat-Breaking-Änderung darstellen würde, die wir nicht durchführen können, würde einen beträchtlichen Teil der Xamarin.Forms-Codebasis entfernen. ListView2 wird Sie dem Metall viel näher bringen, indem Sie diese Elemente entfernen, die als Leitplanken gedacht waren (oder im Fall von Cell die unheilige Fusion von 2 verschiedenen internen Projekten) und jetzt nur noch alle verletzen.

Die alte Caching-Strategie wirkt sich auf JEDEN heute existierenden Renderer aus. Dies ist der Grund, warum jeder Renderer die Änderung seines Elements unterstützt. Wenn das nach meiner besten Schätzung weggeht, gehen etwa 10 % des gesamten Codes im Projekt weg. Es ist wirklich der größte Krebs des Projekts.

@davidortinau du bekommst deinen eigenen Kommentar, nur weil deiner so viele schöne Formatierungen hat!

Wenn ich diesen Ansatz verwende, um meine Anwendung auf der obersten Ebene zu beschreiben, erhalte ich:

  • eine App, die auf jeder Plattform gleich aussieht
  • Materialdesign (in diesem Fall) Muster standardmäßig aktiviert
  • die neuesten Navigationsmuster mit Konfiguration aktiviert
  • Ich muss nicht arbeiten, um den Eintrag oder die Schaltfläche so anzupassen, dass sie auf iOS und Android und UWP gleich aussieht?

Ist das genau? Andere Vorteile, die ich hervorheben sollte?

Ja, das ist richtig. Es gibt viele andere Vorteile, die Sie hervorheben können, aber sie sollten offensichtlich werden, sobald Sie anfangen, damit herumzuspielen. So können Sie untere Blätter machen, einen FAB haben, mit URLs navigieren (Update kommt noch) und vieles mehr.

Anstelle von App habe ich MaterialShell. Ich muss ein neues Anwendungsparadigma auf höchster Ebene erlernen/anwenden, um davon zu profitieren?

Falsch. Die MainPage Ihrer Apps ist die MaterialShell. Die Anwendung ist immer noch Ihr App-Root.

Sobald ich in meiner App bin, bin ich wieder im ContentPage-Land, richtig? Aber alle meine Buttons und Einträge sind materiell und hübsch.

Mit der Ausnahme, wo du oben falsch lagst, ja, das ist richtig.

Kann ich trotzdem OnPlatform und dergleichen vom Aussehen (oder Verhalten) abweichen, um auf einer anderen Plattform anders zu sein?

Jawohl.

Wie sieht mein Migrationspfad von einer vorhandenen App zur Verwendung dieser "Shell" aus?

Schauen Sie sich den Repro-Fall des Google Play Store an und stellen Sie sich vor, alle Ihre aktuellen Seiten Ihrer Apps darin abzulegen. Dadurch werden nur die Bereiche in Ihrer App ersetzt, in denen Sie Nav-/Tab-/MD-Seiten direkt verwenden. Es hat keine Auswirkungen auf Ihre ContentPages.

Ich stelle die neue MaterialShell vor, beschreibe, wie meine App strukturiert und aussehen soll, und führe sie einfach aus, um die neue Güte zu sehen?

Bingo

Welche Optionen habe ich, wenn mir das Aussehen des Flyouts oder der Menüelemente gefällt, ich sie aber an meine Designer-Kompositionen anpassen muss?

Sie haben die volle Kontrolle über die Kopfzeile, wie die Kopfzeile ein- und ausgeblendet wird. Sie können das Aussehen und Verhalten jeder der "Zellen" (sie werden keine Zellen sein) im Flyout vollständig steuern. Sie haben auch die vollständige Kontrolle über die Kopfzeile für jede Gruppe darin. Tatsächlich steuern Sie das "Aussehen" von allem, aber wir müssen noch ein paar zusätzliche Orte hinzufügen, damit Sie zusätzlichen Inhalt platzieren können.

An welchem ​​Punkt sage ich "Ugh, ich hätte das alles selbst ausführen sollen" und verschiebe, was ich habe, in eine standardmäßige Xamarin.Forms-App-Struktur?

Wenn das Flyout für das physische Layout des Google Play Store ganz anders aussieht als gewünscht. Nicht ganz anders, ganz anders.

Wenn ich die MaterialShell komplett aufgeben muss, verliere ich dann all diese Styling-Güten und bin wieder da, wo ich angefangen habe (wie heute) mit einem Eintrag, der zwischen iOS und Android und UWP ganz anders aussieht? Ich möchte nicht.

Keine MaterialShell legt nur einige Standardressourcen fest, damit ihre Kinder sie erhalten. Sie werden das selbst tun können. Möglicherweise müssen Sie es trotzdem tun, wir haben uns nicht dazu verpflichtet, MaterialShell standardmäßig dazu zu bringen, dies zu tun. Wenn wir es zu einem Opt-in anstelle eines Opt-out machen, ist es ein einzelner API-Aufruf für jeden Unterbaum.

Es gibt einen Wendepunkt, den ich erwarte. Nachdem ich diesen Ansatz verwendet habe, um schnell loszulegen, werde ich auf einige Einschränkungen stoßen und muss meine Optionen erkunden. Was sind das und wann ist es besser, MaterialShell nicht zu verwenden?

Die Absicht ist, dass Sie NIE besser dran sind, ohne Shell zu sein. Sie möchten vielleicht kein Material, aber Sie sollten immer Shell haben (wieder kommt die Shell-Basisklasse). Wieso den? Das Erscheinungsbild der Shell wird viel konfigurierbarer sein, die Navigationsgeschichte wird viel einheitlicher sein, es sollte nichts vernünftiges geben, was Sie mit den anderen Seiten tun können, was Sie mit Shell nicht tun können.

Besser ist es, sicherzustellen, dass die Shell-Renderer tatsächlich einfach zu konfigurieren und vernünftig sind. Keine magischen versteckten Klassen, keine benutzerdefinierten Unterklassen der nativen Ansicht, auf die wir uns stark einlassen. So weit wie möglich wird jede Komponente der Renderer zusammengestellt und austauschbar. Auf diese Weise können Sie es tatsächlich reparieren, wenn es nicht so funktioniert, wie Sie es möchten ...

Warum haben wir das nicht zuerst gemacht? Es war in den Anfangstagen kein Designziel und dann sind wir einfach damit verheiratet... Das ist groß genug und neu genug, dass wir diesen Fehler nicht mit uns tragen müssen.

@opcodewriter

Im Ernst, in wie viele verschiedene Richtungen kann Xamarin Forms gehen? Das XF-Team ist kaum in der Lage, die aktuelle XF-Implementierung zumindest für Android und iOS zu reparieren, und jetzt das?

Wie sieht es mit der Fehlerbehebung, der Korrektur der XAML-Vorschau und der Leistung aus?

^^ Das

@migueldeicaza

Leute, gestern hatten Jason und ich eine Diskussion darüber, wie wir diese Spezifikation verbessern können und wir werden ein großes Update durchführen, wir teilen dies in verschiedene Themen auf.

Miguel, das wird eindeutig eine große Aufgabe. Ich kann nicht im Namen aller Entwickler sprechen, aber ich kann Ihnen sagen, dass mein Team drei Dinge will: Stabilität, Leistung und Flexibilität. Wir wollen, dass Fehler behoben werden. Wir möchten, dass unsere App reibungslos läuft, und wir möchten die Designs, die uns unsere UI/UX-Designer geben, umsetzen können, ohne sich umzudrehen und zu sagen "Sorry, das ist auf unserer Plattform einfach nicht möglich". Diese Spezifikation scheint diesem Ziel zu widersprechen. Dies erfordert, dass mehr Ressourcen für die Arbeit eingesetzt werden, was bedeutet, dass Ihre Ressourcen nicht für die Arbeit an Stabilität, Leistung und Flexibilität frei werden.

Wäre dies das neue Standardverhalten/die neue Methode zur Entwicklung in xamarin-Formularen? Oder hätten wir immer noch die Möglichkeit, unsere Apps mit jedem plattformspezifischen Look and Feel zu erstellen?

@DanielCauser während ich vermute, dass dies auf lange Sicht der "Standard"

Ich befürworte diese Idee vorsichtig, sofern die vorgeschlagenen Verbesserungen durch Verbesserungen im zugrunde liegenden Xamarin Forms-Code ausgearbeitet werden. Wenn dies die Komplexität von Formularen erhöht, würde ich es nicht verwenden.
Für mein Geld würde ich jedoch viel lieber Entwicklerressourcen haben, die darauf ausgerichtet sind, Forms flexibler, schneller und fertiger zu machen, als es derzeit ist. Wenn das passiert, könnte ich alle vorgeschlagenen neuen Funktionen hier für mich selbst erstellen. DIY passt in diesem Fall mit ziemlicher Sicherheit besser zu mir und meinen Kunden als ein generisches Toolkit von Xamarin, so gut es auch sein mag. Mit ein paar bemerkenswerten Ausnahmen löst dieser Vorschlag nicht die Probleme, mit denen ich im Moment konfrontiert bin.

@jassmith

  1. Es gibt mehr als 500 offene Fragen.
  2. Xamarin Forms ist 3 Jahre alt und es gibt immer noch Fehler in den grundlegenden Steuerelementen und Funktionen, wichtige Funktionen fehlen noch und die Leistung ist noch nicht vollständig festgelegt (ich weiß, dass einige Verbesserungen vorgenommen wurden, aber die Leistung auf Android ist unterdurchschnittlich).
  3. Das Xamarin Forms-Entwicklungsteam ist immer noch unterdimensioniert.

Warum möchten Sie jetzt mit der Arbeit an dieser völlig neuen Funktion beginnen? Ist es nicht sinnvoller, sich zuerst auf das oben Genannte zu konzentrieren?

Zu Ihrem obigen Kommentar zu ListView: Ich begrüße jede Art von kühnen Ansichten, einschließlich einer vollständigen Neugestaltung \ des Ersetzens. Es ist nicht so, dass in Xamarin Forms alles so großartig ist, dass Dinge nicht angefasst\verändert werden sollten.

@opcodewriter

1) Ja, es gibt. Ich stimme zu, dass es ein Problem ist und weiterhin die vorrangige Arbeitsaufgabe sein wird, auf die ich persönlich dränge.

2) Die Leistung auf Android ist einer der treibenden Gründe dafür. Dies gibt dem Framework mehr Zeit für Seitenübergänge, sodass wir Dinge wie die JIT-Zeit ausblenden können. Wir können Seiten viel intelligenter proaktiv laden und aufbewahren. Was das XF-Team nicht beheben kann, ist die gesamte JIT-Zeit. Wenn Sie Ihre App in Android mit aktiviertem AOT ausführen und es viel schneller ist, kann ich nichts tun, um Ihnen zu helfen.

3) Keine Argumente hier.

Warum möchten Sie jetzt mit der Arbeit an dieser völlig neuen Funktion beginnen? Ist es nicht sinnvoller, sich zuerst auf das oben Genannte zu konzentrieren?

Diese Arbeit ist nicht geplant, wir diskutieren hier nur eine Spezifikation. Mein Management wird es planen, wenn sie es mit meinem Rat für angemessen halten.

Zu Ihrem obigen Kommentar zu ListView: Ich begrüße jede Art von kühnen Ansichten, einschließlich einer vollständigen Neugestaltung \ des Ersetzens. Es ist nicht so, dass in Xamarin Forms alles so großartig ist, dass Dinge nicht angefasst\verändert werden sollten.

ListView ist wirklich der Bug Bear von Xamarin.Forms. Von diesen 500 Problemen, von denen 220 als Fehler markiert sind (es gibt auch viele Probleme mit der Verwaltung oder Verbesserung), haben nördlich von 25% nur mit ListView zu tun. Zum Vergleich, das ist ungefähr der gleiche Prozentsatz, der mit der gesamten UWP-Plattform zu tun hat. Schlimmer noch, eine ganze Reihe der Crasher in Android, die im Grunde als Renderer nach dem Entsorgen verwendet werden, sind auch ListView-Fehler, die jedoch in meiner Suche wahrscheinlich nicht auftauchen, da ListView nirgendwo in der Suchanfrage auftaucht.

@jassmith neben der Behebung bestehender Probleme (neben ListView gibt es andere Dinge, die immer noch nicht immer richtig funktionieren), gibt es auch wichtige Funktionen, die weggelassen wurden (zufällige Reihenfolge):
- Echte Popup-Unterstützung (grundlegende und allgemeine Funktion fehlen noch)
- Seitennavigation beim Zurücknavigieren abbrechen (lang ausstehendes Problem)
- Grundsteuerelemente fehlen (keine CheckBox, RadioButton und mehr)
- Plattformübergreifendes Zeichnen (Leinwandsteuerung oder auf andere Weise)
- Unterstützung für das plattformübergreifende Zeichnen von Solid\Gradienten-Pinseln (SolidColorBrush, GradientBrush)

Ich wünschte, es würde mehr Arbeit geleistet, um das Framework wirklich reichhaltiger zu machen, und keine Dinge wie CSS-Stil oder Flexbox (die mit ihren eigenen Problemen kamen) hinzuzufügen.

@opcodewriter

Echte Popup-Unterstützung (grundlegende und allgemeine Funktion fehlen noch)

Fair, es scheint nie hoch genug priorisiert zu werden, um real zu werden. Das ist irgendwann tatsächlich ziemlich weit gekommen.

Seitennavigation beim Zurücknavigieren abbrechen (lang ausstehendes Problem)

Dies ist eigentlich etwas, was MaterialShell ansprechen soll. Es gibt ziemlich solide Gründe, warum dies in NavigationPage nicht möglich ist.

Grundlegende Steuerelemente fehlen (keine CheckBox, RadioButton und mehr)

Einige davon sind Teil der F100-Initiative, die jetzt läuft.

Plattformübergreifendes Zeichnen (Leinwandsteuerung oder auf andere Weise)

Das wäre die Schwester-API dazu, wie in #2452 angegeben

Unterstützung für das plattformübergreifende Zeichnen von Solid\Gradienten-Pinseln (SolidColorBrush, GradientBrush)

Gleiche Antwort wie oben.

@jassmith

Fair, es scheint nie hoch genug priorisiert zu werden, um real zu werden. Das ist irgendwann tatsächlich ziemlich weit gekommen.

OK, ich freue mich darauf, es bis Ende 2018 zu priorisieren :)

Dies ist eigentlich etwas, was MaterialShell ansprechen soll. Es gibt ziemlich solide Gründe, warum dies in NavigationPage nicht möglich ist.

Könnten Sie bitte genauer angeben, warum dies in der aktuellen Implementierung nicht möglich ist?

Einige davon sind Teil der F100-Initiative, die jetzt läuft.

Ich verstehe. Daumen drücken..

Könnten Sie bitte genauer angeben, warum dies in der aktuellen Implementierung nicht möglich ist?

Ich werde hier nicht weiter darauf eingehen, weil wir massiv vom Weg abkommen, aber der Kern ist wie folgt:

  • Sie können die Zurück-Wischgeste in iOS nicht reaktiv abbrechen. Da dies die primäre Methode ist, mit der die Leute mit den größeren Telefonen zurück navigieren, wird dies zu einer eklatanten Auslassung.
  • Obwohl es technisch möglich ist, dieses Verhalten in iOS zu überschreiben, erfordert es, ziemlich tief in die Interna des UINavigationController einzusteigen, sodass wir nicht sicher sein können, ob es tatsächlich unterstützt wird oder funktioniert, wenn eine neue Version von iOS herauskommt. Kurz gesagt, Apple scheint es nicht wirklich zu genießen, wenn die Leute dies tun.

Es gibt auch einige andere kleinere Bedenken hinsichtlich der Auswirkungen auf das Styling. Das ist jedoch die lange Rede kurzer Sinn. Wenn Sie dieses spezielle Feature dennoch diskutieren möchten, schlage ich vor, eine neue Ausgabe zu eröffnen :)

@jassmith
Ich dachte, es wäre genug, nur gestureRecognizerShouldBegin handhaben und so etwas wie OnBackButtonPressed anzurufen.

Insgesamt gefällt mir sehr viel von dem, was ich lese, aber dies fühlt sich nicht wie etwas an, das im Kern von Xamarin Forms nuget/repo gemacht werden sollte.

Dies ist ein eigenwilliger Ansatz, der auf Xamarin Forms aufbauen und nicht darin integriert werden sollte. Ich sehe dies als eine separate Bibliothek, die es Entwicklern ermöglicht, einen anderen Ansatz zu verfolgen. Die erforderlichen Teile von Xamarin Forms, die verfügbar gemacht werden müssen, sollten sein, und dies sollte auf diesen Bits aufbauen.

Genau wie wenn Entwickler sich für Xamarin Classic/Native oder Xamarin Forms entscheiden, sehe ich eine ähnliche Entscheidung für Xamarin Forms oder Xamarin Forms mit Shell.

Xamarin Forms sollte sich darauf konzentrieren, das beste plattformübergreifende UI-Framework zu erstellen, ohne zu versuchen, Plattformen so anzupassen, dass sie einander ähneln. Heute leistet Xamarin Forms hervorragende Arbeit, um sicherzustellen, dass das Plattformgefühl respektiert wird.

Ich konnte sehen, dass sich eine Basis-Shell im Xamarin Forms-Repository und etwas Code für die Verarbeitung von Shells befindet, aber die Material Shell scheint zu eng mit einer bestimmten Entwurfssprache und einem bestimmten Navigationsmuster verbunden zu sein, um zu glauben, dass sie im Xamarin Forms-Repository enthalten sein sollte.

@MisterJimson
Vielen Dank für dein Feedback. Die genaue Platzierung der öffentlichen API-Fläche steht noch nicht fest. Es gibt Vor- und Nachteile beider Ansätze.

Die Spezifikation wird (hoffentlich sehr bald) aktualisiert, um sowohl eine Shell- als auch eine MaterialShell-Klasse zu haben. Die MaterialShell-Klasse wäre der Teil, den wir in Betracht ziehen, aus dem Kern herauszukommen. Shell wäre das, was du beschrieben hast.

Aktualisiert mit Shell Breakout und Aktualisierung der Navigationsspezifikationen

Ich würde es wirklich begrüßen, wenn die vorhandene XF-Implementierung ... stärker und besser wäre, damit so etwas als Addon existiert, nicht als Teil von BCL. Eine starke zugrunde liegende Plattform, die korrekt und stabil ist, wird also bestehenden Apps und allen neuen Ebenen wie dieser zugute kommen.

Freue mich auf die Entwicklung dieser Sache.

@jassmith @brianlagunas

Nur ein paar Beobachtungen.

  • BackButtonBehavior, sollte es doch eine Sichtbarkeitseigenschaft geben, falls Sie sie gar nicht wollen?
  • Das Materialschalen-Navigationsschema ist wie Prism, wird es mit diesen bestehenden Frameworks funktionieren? (Prisma, FreshMVVM, MVVMCross)
  • Können Sie das Layout in der Navigationsleiste vollständig überschreiben? Derzeit ist Forms in dieser Hinsicht äußerst eingeschränkt und Sie haben am Ende klobige Navigationsleisten, die Sie auf die Route des Kundenrenderers zwingen, in der Gewissheit, dass eine neue Version von Forms höchstwahrscheinlich Ihren benutzerdefinierten Code zerstört.
  • MasterDetail wird nicht viel berührt, können Sie das Flyout-Menü anpassen?
  • Welche Kontrolle haben wir über den Hamburger?

Ich möchte nur sicherstellen, dass bestehende Schwachstellen und Einschränkungen angegangen werden sowie neue Funktionen erhalten werden.

Klingt gut.

Ich bin sehr neu bei XF, aber das Framework hat den Ruf, etwas zerbrechlich zu sein, obwohl dies dank Ihrer Bemühungen sicherlich schnell verbessert wird.

Also für das, was es wert ist, das ist meine Meinung :-)

Es ist großartig, dass Xamarin im Moment viel Liebe bekommt , aber ich stimme vertragen .

Ich mag auch die Gedanken von @MisterJimson, dass dies eine andere Ebene sein sollte - aber Sie müssen ehrlich zu sich selbst sein, was Ihre Kapazitäten

Ich habe genug Probleme, meinen Code zum Laufen zu bringen, ohne mir Sorgen um den von anderen machen zu müssen :-)

XF ist im Moment an einem guten Ort, es hat das Potenzial, ein wirklich solides Toolset zu werden.

Danke für all Ihre harte Arbeit, das zeigt sich.

@mackayn

BackButtonBehavior, sollte es doch eine Sichtbarkeitseigenschaft geben, falls Sie sie gar nicht wollen?

Legen Sie den Befehl so fest, dass CanExecute false zurückgibt. Ich habe mich entschieden, im Moment keine sekundäre Methode hinzuzufügen.

Das Materialschalen-Navigationsschema ist wie Prism, wird es mit diesen bestehenden Frameworks funktionieren? (Prisma, FreshMVVM, MVVMCross)

Ich hoffe doch! Ich bin mir nicht sicher, aber ich dachte an sie und all ihre Probleme. Aus diesem Grund erfolgt zum Beispiel die gesamte Navigation durch ein einziges Ereignis.

Können Sie das Layout in der Navigationsleiste vollständig überschreiben? Derzeit ist Forms in dieser Hinsicht äußerst eingeschränkt und Sie haben am Ende klobige Navigationsleisten, die Sie auf die Route des Kundenrenderers zwingen, in der Gewissheit, dass eine neue Version von Forms höchstwahrscheinlich Ihren benutzerdefinierten Code zerstört.

Dieser Teil ist schwieriger. Ich möchte hier so viel Erweiterbarkeit wie möglich zulassen, aber ich bin wirklich offen für Vorschläge, wie man dies auf vernünftige und vernünftige Weise verbessern kann.

MasterDetail wird nicht viel berührt, können Sie das Flyout-Menü anpassen?

Sie können die Kopfzeile auf eine beliebige Ansicht einstellen, die für Gruppenkopfzeilen und Elemente verwendete Vorlage steuern und Menüelemente hinzufügen. Sie steuern einige Aspekte des Layouts, aber nicht zu 100%. Auch hier wäre es gut, sich ein paar Gedanken darüber zu machen, was Sie sonst noch brauchen. Ich sehe eindeutig die Notwendigkeit für eine Fußzeile mit einer Footer-Verhaltenseigenschaft.

Welche Kontrolle haben wir über den Hamburger?

BackButtonBehavior überschreibt auch den Hamburger. Vielleicht sollte es umbenannt werden. Auch hier bin ich für Vorschläge offen. Ursprünglich habe ich es LeftBarButton genannt, aber in RTL-Situationen ist es nicht links...

Die technische Rückzahlung von

Enge Interaktionen zwischen Tabbar und Navbar ist ein solcher Bereich. Sicherstellen, dass das Navigieren zwischen Tabs oder Elementen im MDP störungsfrei ist, ist ein weiterer Bereich. Es gibt viele Bereiche, in denen kleine Probleme auftreten, da nicht jedes Element die Shell Ihrer App ganzheitlich betrachten kann.

Was die Werkzeuge angeht, gibt es dafür ein völlig separates Team, das große Fortschritte macht. Das interne Tooling hat sich in den letzten 6 Monaten massiv verbessert und ich freue mich sehr darauf, dass Sie das ausprobieren können!

@mackayn

Das Materialschalen-Navigationsschema ist wie Prism, wird es mit diesen bestehenden Frameworks funktionieren? (Prisma, FreshMVVM, MVVMCross)

Keine Angst,

@dansiegel

Gut zu wissen, dass beide Teams im Dialog sind, mehr brauchte ich nicht zu wissen

@jassmith Es ist mittlerweile offensichtlich, dass einige Dinge in XF laufen oder architekturiert wurden, nicht die beste ist. Anstatt also Lippenstift auf das Schwein zu auftragen (um hier nicht unhöflich sein zu wollen), warum nicht entweder ein neues Framework von Grund auf neu erstellen oder das bestehende massiv überarbeiten. Ich weiß, es klingt sehr beängstigend, aber ich bin mir ziemlich sicher, dass die große Mehrheit der Xamarin Forms-Entwickler nichts dagegen hätte.
Ich habe erlebt, dass PR mit gutem Refactoring abgelehnt wurde, weil "wir diese Art von Änderungen nicht wollen". Ich bin mir nicht sicher, wer diese Regel aufgestellt hat, aber er sollte tief durchatmen, sich entspannen und vielleicht die "Regel" überdenken.
Was ist das Beste: Haben Sie weiterhin frustrierte Entwickler, die ein Framework verwenden, das nicht mithalten kann, oder frustrierte Entwickler, die einige Refactoring-Arbeiten durchführen müssen? Nur meine 2 Cent...

@opcodewriter Sie und ich stimmen zu, aber dies ist für diese Spezifikation nicht zum Thema.

Lesen Sie einfach das neue Material rund um die Navigation und es gefällt mir sehr. Ich liebe es, eine Sortierhand zum Binden von Navigationsbefehlen zu haben und die Navigation an URLs auszurichten (wie und ich nehme an, dass sie von Prism beeinflusst wurden) ist klug.

Ironischerweise war das URI-Navigationsschema etwas, das wir schon vor langer Zeit machen wollten und haben Prism auf die Implementierung gedrängt, weil wir es nicht vernünftig in das Framework integrieren konnten. Um nichts von ihrem Kredit zu nehmen, verdienen sie 100% davon :)

Die genaue Semantik der Kurzschrift steht noch aus.

Ich denke, es wird wahrscheinlich eher so enden:

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

oder

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

So können die Erweiterungen genauer sein, welche Parameter sie annehmen. Der Namespace wird hauptsächlich verwendet, um Dinge mit Intellisense leicht auffindbar zu machen.

@jassmith Ich mag dieses Segue-Zeug wirklich. Darf ich fragen, wie Sie Push-Modal unterstützen wollen?

Ich habe nicht alle Details, aber ich könnte mir ein URL-Nav wie ein Prisma vorstellen, das in Markup-Erweiterungen verpackt ist.

<!-- 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" />

Zunächst ist zu beachten, dass die URI-Navigation nur mit Shell funktioniert. Es ist der einzige Ort, an dem wir den Stack konsequent verstehen können, ohne seltsame Randfälle zu haben, und wir können die Navigationsinteraktionen so gestalten, dass sie das Konzept unterstützen.

Derzeit unterstützen wir nur vollständige URIs. Partials sind viel schwieriger zu handhaben, weil sie kontextabhängig sind.

Ihre 3 Beispiele wären dann, vorausgesetzt, der aktuelle Standort ist: app://Shell/Apps/Games/Details

Dies bedeutet insbesondere, dass Sie sich in einer Shell befinden, deren aktuelles ShellItem die Apps-Route hat, deren aktuelles ShellTabItem die Games-Route hat, deren Inhaltsseite auf ihren Stack verschoben wurde, die die Routendetails enthält.

<!-- 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" />

In einem Shell-URI ist der erste Ort immer eine Shell. Ist dies nicht der Fall, wird davon ausgegangen, dass es sich um einen modalen Push handelt. Als nächstes kommt das ShellTab, dann das ShellTabItem. Danach folgt der Navigationsstack des ShellTabItem. Ich habe derzeit nicht die Absicht, URI-Nav auf alle möglichen Seitensteuerelemente zurückzuportieren. Das wird WIRKLICH haarig mit Leuten, die MasterDetailPages verwenden...

Mit Routenregistrierung und Routeneigenschaften ist kein typbasiertes Routing erforderlich. Ich werde es aus der Spezifikation entfernen.

@jassmith denkt mehr über diese Navigationssachen nach und ich habe einige Fragen

  1. Wie kannst du mit CanExecute umgehen
  2. Wie können Sie dem Benutzer die Kontrolle über mehrere Taps geben (Lesen verhindern)?
  3. Wie gehen Sie mit der relativen Navigation um? Dh Sie sind 3 Seiten tief und müssen auf die vierte Seite gehen, aber der Stack ist voll dynamisch?
  4. prisma hat diese fantastische Vorstellung von NavigationParameters wodurch wir nicht nur grundlegende Werte über den Abfragestring /Navigation/MyPage/MyPageDetails?id=33 , sondern auch komplexe Objekte new NavigationParameters {{nameof(MyObject), MyObject}} . Planen Sie, etwas Ähnliches zu unterstützen?

@ChaseFlorell

1) Mit Übergängen? Sie können derzeit nicht. Es muss auf jeden Fall mehr darüber nachgedacht werden. Es gibt eine Möglichkeit, einen Segue-Befehl zu machen, aber es ... ist scheiße. Das würde Sie damit umgehen lassen, aber zu diesem Zeitpunkt lohnt es sich WIRKLICH nicht.

2) Ein Segue deaktiviert sich selbst, bis der Push abgeschlossen ist. Weitere Versuche, den Befehl no-op zu aktivieren, bis die vorherige Navigationsaufgabe abgeschlossen ist.

3) Sie können eine traditionelle Navigation wie Push/Pop mit Übergängen verwenden. Dies sind relative Aktionen.

4) [QueryParameterAttribute] kann bereits existieren oder nicht, kann ich weder bestätigen noch dementieren. ;)

Es ist unwahrscheinlich, dass wir Unterstützung für komplexe Objekte hinzufügen werden. Die Idee ist, dass Sie Konverter verwenden, um Ihre einfachen Werte in komplexe Objekte umzuwandeln.

Aus früheren Erfahrungen mit der Erstellung einer URI-basierten App-Navigation (zurück im CAB-Composite-UI-Anwendungsblock für p&p) würde ich dringend empfehlen, dass Sie nicht den Typ System.Uri verwenden und stattdessen alles wie eine URI aussehen @pprovost kann die lebenslangen Narben bezeugen, die die Arbeit in ihm hinterlassen haben muss. Ich erinnere mich, dass ich unzählige Probleme hatte, als wir mit Internet-URI- Beschränkungen und Fehlern (zB bei Hostnamen) konfrontiert waren, die uns nicht weniger wichtig waren in-App-Zeug.

Ein Teil des Schadens ist schon angerichtet , nehme ich an.

Tatsächlich ist System.Uri die beste Wahl, wenn ein URI-basiertes Navigationsschema unterstützt wird. Während CAB die URI-Navigation verwendet hat, hat es auch getan, was Sie sagen, und es "wie ein URI aussehen" lassen, indem es Ihnen erlaubt, Zeichenfolgen anstelle des System.Uri-Objekts zu verwenden. Hostnamen waren nie erforderlich.

Was Sie verlangen, ist eine sehr lose String-basierte API, die jede von Ihnen eingegebene String-Syntax akzeptieren kann, was nicht zu vorhersehbaren Ergebnissen führt. Es müssen Regeln vorhanden sein, damit ein URI/String-basiertes Navigationsschema funktioniert.

Ein beliebiger URI funktioniert auch in XF nicht. Die Liste der ungültigen Zeichen in einer URL, die jedoch in einem Dateisystem gültig sind, ist nicht gerade klein. Das sind alles Fälle, in denen ein String funktioniert hätte und ein URI nicht entkommen oder der Benutzer herausfinden muss, warum die Dinge nicht funktionieren (oder fehlschlagen?) und Dinge in "URI-sicher" umbenennen.

Sie können Ihre eigene Abstraktion erstellen, wenn Sie restriktivere (oder bessere Semantik/Parsing/Validierung?) wünschen, aber IMHO bringt System.Uri eine Menge Internet-Gepäck mit sich, das nicht kostenlos ist. Dies ist ähnlich wie Mono/MonoDevelop seinen eigenen FilePath erstellt hat , um Pfade darzustellen, die normalerweise nur Strings sind.

Zumindest scheinen alle URIs als relativ betrachtet zu werden, was die Dinge vereinfacht. In CAB haben wir auch absolute Uris mit Schema- und Hostnamen-Teilen verwendet, was problematisch war.

Ich würde lieber etwas wie ein ResoucePath sagen, als ein Uri . Aber so spät im Spiel bin ich mir ziemlich sicher, dass es sowieso erledigt ist.

Ich bin mir nicht sicher, was Ihrer Meinung nach Dateisystempfade mit irgendetwas zu tun haben ...

Wie würden Sie einen URI verwenden, um das System zu verwirren? Es wird das Schema und den Hostnamen ignorieren und nach Routen suchen (die nur auf [az] beschränkt sind). Wenn die seltsamen Zeichen, die Sie eingeben, nicht gefunden werden können, hört es einfach auf. Und die eingegebene Abfragezeichenfolge muss gültige C#-Bezeichner sein, oder sie wird einfach nicht abgeglichen. Escape-Daten in den Abfragezeichenfolgendaten werden nicht mit Escapezeichen versehen.

@kzu URI funktioniert in XF

Macht Sinn. Danke für die Hintergrundinfos zu Prism @brianlagunas! Jetzt sollte ich die Spezifikation sorgfältig lesen und einige wirklich nützliche Rückmeldungen geben ;)

Sehr gute Initiative, aber ich hoffe, dass Erweiterbarkeit und Anpassung berücksichtigt werden, indem die richtigen virtuellen Methoden oder andere Möglichkeiten geschaffen werden, um unser "besonderes" Ding für unsere Kunden zu erledigen.

Wird es zum Beispiel möglich sein / wie:

  1. Erweiterbarkeit der Registerkarten, die beispielsweise ein Abzeichen mit einem Symbol anzeigen. Oder zeigen Sie eine Popup-Schublade darüber an, z. B. eine Schaltfläche "Mehr" oder " * ".
  2. Benutzerdefinierte Snackbar (z. B. mit der Schaltfläche "Rückgängig" für eine Aktion, die Sie gerade mit benutzerdefinierten Hintergrund-/Vordergrundfarben ausgeführt haben)
  3. Fragment-Pushing in Android mit anderen Animationen als den in der Shell programmierten Standard, wie keine Animation, um die schnellstmögliche Navigation zu ermöglichen.

Ein technischer Hinweis: Wird die Shell Seiten recyceln, sodass die nativen Elemente nach zweimaligem Navigieren zu einer Seite mit einer anderen VM darunter wiederverwendet werden?

Hallo @rogihee

Ich freue mich über Ihr Feedback zur Umsetzung. Ich finde es verrückt erweiterbar: https://github.com/xamarin/Xamarin.Forms/blob/9558f2837280e02b41848d3a3c3213d49a664751/Xamarin.Forms.Platform.iOS/Renderers/ShellRenderer.cs

Android befindet sich derzeit noch in der Entwicklungsphase, verwendet jedoch einen identischen Ansatz.

@rogihee Was das Recycling von Seiten

Sieht gut aus diese "Erstellen*"-Optionen. Es ist schön, die schnellen Fortschritte zu sehen!

Ich frage mich, ob die Wiederverwendung von Elementen Auswirkungen auf die Leistung hat. Persönlich würde ich die Geschwindigkeit und das "flüssige" Gefühl einer App einer höheren Mem/CPU-Auslastung vorziehen (obwohl es am Ende natürlich irgendwo eine Korrelation gibt). Und priorisiere iOS / Android über alles andere :-).

Shell konzentriert sich sehr auf die Wahrnehmung von Fluidität. Es ist noch nicht überall, aber es kommt zusammen.

Ich muss wirklich einige frühe Benutzer dazu bringen, verrückte Dinge mit der Shell zu tun, um sicherzustellen, dass sie die Last bewältigen kann, für die sie ausgelegt ist.

@jassmith mig hat gerade 3 Minuten lang Shell in Build erwähnt .....

Ich bin nicht sein Papa

+1

Aktualisierte API, um dem aktuellen Zustand der Welt zu entsprechen, die Beispiele müssen noch aktualisiert werden.

Einige aktualisierte Beispiele wurden hinzugefügt, es muss noch viel Arbeit an der Korrektur anderer Beispiele und der Aktualisierung von Routenbeschreibungen geleistet werden, wenn die Kurzschriftsyntax verwendet wird (da Sie Kurzschriftrouten erhalten!)

Meine Güte, ich komme so spät zur Party. Toller Bericht und Diskussion. Ich habe alles überflogen (sorry am Flughafen) und habe einen eigenen Vorschlag. Sorry, falls das woanders erwähnt wurde.

@jassmith @migueldeicaza Können Sie bitte der Navigationsleiste ein Verhalten hinzufügen, damit sie beim Scrollen der ListView weggescrollt und beim Scrollen in die entgegengesetzte Richtung angezeigt werden kann. Fast jede professionelle App da draußen tut dies, um mehr Immobilien anzuzeigen. Dies wäre besonders bei kleinen Geräten nützlich.

Eine andere ist, warum benennen Sie die XAML-Tags nicht um, damit sie einfacher zu verstehen sind? Vielleicht Tab anstelle von ShellSection verwenden? Es gibt jetzt viele ShellX-Tags.

Für iOS gibt es meiner Meinung nach eine Eigenschaft zum Ein- und Ausschalten, um den Bildlaufmodus in der Navigationsleiste zu aktivieren. Für Android müssen Sie die neuen Layouts (CoordinatorLayout, AppBarLayout usw.) verwenden. Die Android-Implementierung von XF ist in dieser Hinsicht ziemlich veraltet, da sie immer noch ein RelativeLayout als Hauptcontainer verwendet. Ich denke, es gibt irgendwo ein Verbesserungsticket zu diesem speziellen Problem. Ich würde gerne sehen, dass Shell verschiedene Scroll-Modi unterstützt.

Außerdem müssen wir oft benutzerdefiniertes Verhalten implementieren, um Fehler/andere Arten von Popups auf der Seite anzuzeigen. Shell sollte diese Funktionalität sofort unterstützen, damit wir nicht auf Plugins von Drittanbietern zurückgreifen oder eine komplexe UI-Hierarchie erstellen müssen.

@adrianknight89

Können Sie bitte der Navigationsleiste ein Verhalten hinzufügen, damit sie beim Scrollen der ListView weggescrollt und beim Scrollen in die entgegengesetzte Richtung angezeigt werden kann. Fast jede professionelle App da draußen tut dies, um mehr Immobilien anzuzeigen. Dies wäre besonders bei kleinen Geräten nützlich.

Das ist etwas, was ich wirklich versuche, den richtigen Weg zu finden. Leider unterstützen nicht alle Plattformen diese Funktion, daher wird es wahrscheinlich ein plattformspezifischer Deal sein. Android wurde zumindest von Grund auf entwickelt, um dies zu unterstützen. Ich schalte es gelegentlich ein, um sicherzustellen, dass es noch funktioniert.

Eine andere ist, warum benennen Sie die XAML-Tags nicht um, damit sie einfacher zu verstehen sind? Vielleicht Tab anstelle von ShellSection verwenden? Es gibt jetzt viele ShellX-Tags.

Die Namensgebung hier ist WIRKLICH schwer. ShellTab ist etwas verwirrend für oben vs. unten. Ich habe mich stattdessen für allgemeinere hierarchische Namen entschieden, muss jedoch zugeben, dass ich mit der Namensgebung nicht zufrieden bin. Vorschläge sind zu 100 % willkommen ... freuen sich nicht ganz darauf, ihre Namen WIEDER umzugestalten, aber was können Sie tun ...

Für iOS gibt es meiner Meinung nach eine Eigenschaft zum Ein- und Ausschalten, um den Bildlaufmodus in der Navigationsleiste zu aktivieren. Für Android müssen Sie die neuen Layouts (CoordinatorLayout, AppBarLayout usw.) verwenden. Die Android-Implementierung von XF ist in dieser Hinsicht ziemlich veraltet, da sie immer noch ein RelativeLayout als Hauptcontainer verwendet. Ich denke, es gibt irgendwo ein Verbesserungsticket zu diesem speziellen Problem. Ich würde gerne sehen, dass Shell verschiedene Scroll-Modi unterstützt.

Shell verwendet CoordinatorLayout + AppBarLayout und "deaktiviert" im Grunde die Unterstützung für das Wegscrollen für den Moment, es funktioniert jedoch. iOS Scroll Off ist auch einfach zu implementieren. Leider bietet NavigationView von UWP keine Unterstützung für diese Funktion.

Außerdem müssen wir oft benutzerdefiniertes Verhalten implementieren, um Fehler/andere Arten von Popups auf der Seite anzuzeigen. Shell sollte diese Funktionalität sofort unterstützen, damit wir nicht auf Plugins von Drittanbietern zurückgreifen oder eine komplexe UI-Hierarchie erstellen müssen.

Beispiele, ich brauche Beispiele :)

@jassmith

Ich verwende das Konnektivitäts-Plugin von James Montemagno, um auf Änderungen des Datenverbindungsstatus zu achten. Wenn die Internetverbindung unterbrochen wird, empfiehlt es sich, eine Benachrichtigung anzuzeigen, die ein- und ausblendet oder stationär bleibt, bis das Internet wieder online ist.

Auf Instagram wird diese Benachrichtigung direkt unter der Navigationsleiste platziert. Auf Tumblr befindet es sich direkt über der unteren Navigationsleiste. Auf YouTube befindet es sich seltsamerweise unter der unteren Navigationsleiste. Vielleicht kann so etwas zu Shell gehören?

Das vorgeschlagene Popup-Steuerelement überlagert, soweit ich weiß, das vorhandene Fenster, obwohl es leicht zu vernachlässigen ist. Die gerade erwähnte Benachrichtigung und möglicherweise andere Arten von Benachrichtigungen müssen ihr übergeordnetes Fenster nicht überlagern (dh der übergeordnete visuelle Baum reagiert immer noch auf Gesten), daher bin ich mir nicht sicher, ob Popup die richtige Lösung ist.

Shell kann eine Eigenschaft haben, mit der wir definieren können, wie diese Ansicht (nennen Sie sie Benachrichtigung[Ansicht]) aussehen, sowie ihre Platzierung und das Verhalten der Ein-/Ausstiegs-Animation. Im Wesentlichen also eine plattformübergreifende Toast-/Snackbar-Implementierung, die in Shell, INavigation oder etwas anderem integriert ist. Dies würde nicht gezwungen sein, pro Plattform nativ auszusehen, sondern auf allen gleich.

d1c014c0-fc7b-4788-9689-1948a7294426

bc91d3ca-b95f-4485-a917-db6ab47510c1

In Bezug auf die Argumente, die bezüglich Stabilität, Flexibilität usw. vorgebracht werden, ohne die veraltete Architektur von 1.0 loszuwerden, halte ich es für nicht machbar, diese Dinge zu erreichen. Ich bin sehr für ListView2.

@jassmith

  • Haben Sie schon ein Erweiterungsticket für das neue ListView?
  • Wann denkst du, wird v1.0 erscheinen? Gibt es eine Chance, dass wir es bei EOY sehen könnten?

Außerdem habe ich die gleiche Sorge, dass das Team unterdimensioniert ist. Tatsächlich habe ich das in der Vergangenheit schon einmal angesprochen. Ich hoffe, dass das Team in Zukunft noch viel größer werden kann. @davidortinau @migueldeicaza

@jassmith Ich glaube schon seit

Ich bin dafür, diese Art von Toast-Benachrichtigungen zu Shell hinzuzufügen, nur um herauszufinden, wie es gemacht werden sollte.

Können Sie bitte dafür sorgen, dass Sie Seiten innerhalb einer Anwendung beliebig platzieren können, wo immer Sie wollen? Dies ist besonders auf Tablets/Desktops/Laptops (Geräten mit größerem Bildschirm) wichtig, bei denen Sie mehrere Seiten gleichzeitig auf dem Bildschirm haben und nicht unbedingt mit einer geteilten Ansicht (Master-Detailseite) organisieren möchten. Beispiel, siehe Google Maps:

image

Beachten Sie, wie der Inhalt über der Karte "schwebt" (keine geteilte Ansicht). Wenn Sie Dinge wie Registerkarten oder die Navigation innerhalb des schwebenden Bereichs verwenden möchten, können Sie dies mit Xamarin Forms nicht sofort erreichen, da die Seitenhierarchie extrem eingeschränkt ist (kann keine Seite verschachteln). in einer Ansicht). Wir haben tatsächlich unsere eigene benutzerdefinierte Ansicht entwickelt, die ähnliche Funktionen wie NavigationPage bietet, aber eine Ansicht ist, nur damit wir diese Art von Layout erreichen konnten, aber es war viel Arbeit / schwer zu tun.

Es sollte möglich sein, Inhalte (einschließlich Seiten) an einer beliebigen Stelle innerhalb einer Anwendung zu platzieren.

Können Sie bitte dafür sorgen, dass Sie Seiten innerhalb einer Anwendung beliebig platzieren können, wo immer Sie wollen?

Ich bin ein bisschen neugierig @jsiemens, da diese Ansicht auf einem Telefon wahrscheinlich nicht richtig aussehen würde, aber auf Desktop und Tablet großartig aussehen würde. Können Sie erläutern, wie Sie erwarten, dass das funktioniert? Letztendlich wäre ich versucht zu sagen, dass Sie das Region-Konzept von Wpf in Forms einbringen. Meine reflexartige Reaktion ist, dass wir, obwohl ich das Konzept liebe, riskieren, dass eine bereits komplexe Navigations-API einen Doktortitel oder zumindest einen genialen IQ erfordert, was für die Benutzerakzeptanz nicht das Beste wäre.

@dansiegel Zumindest persönlich würde ich wahrscheinlich VSM oder ein Äquivalent verwenden, um die Scroll-Ansicht unten zu verschieben und zu komprimieren, wenn sie unter einem bestimmten Viewport-Schwellenwert liegt (wie es GMaps derzeit tut). Wäre gespannt, wie die Navigation und das Zustandsmanagement dafür funktionieren würden.

Navigation: Das ist sicher kein unüberwindbares Problem, wenn man aus der Perspektive der User Journey beginnt und sich dann ansieht, wie der User es erwartet. Die Navigation müsste beispielsweise auf die Vollbilddarstellung eines Telefons im Vergleich zu einer kleineren Ansicht auf einem größeren Bildschirm reagieren.

Der Benutzer würde das Tablet und die kleinere Ansicht als einen einzigen Navigationsmeilenstein "sehen". Auf einem kleinen Bildschirm könnte es zwei Meilensteine ​​geben. Die Navigation müsste irgendwie responsiv sein.

Als Entwickler müssen wir sicherlich mit dieser Reaktionsfähigkeit umgehen, da sie eine kontextabhängige Sache ist. Wir können uns nicht darauf verlassen, dass das Framework das für uns erledigt, aber das Framework muss es unterstützen.

@jsiemens @dansiegel So wie ich das derzeit handhabe, verwende ich ControlTemplate s. Ich erstelle meine Inhalte vom Typ "Seite" als ContentView s und hoste sie in einem ContentPage (innerhalb eines NavigationPage ), das für die Plattform geeignet ist. Die Verwendung von ControlTemplates bedeutet, dass ich mehrere gebundene ContentViews (normalerweise in einem Grid damit ich Dinge überlagern kann), die basierend auf bindbaren Eigenschaften in den ControlTemplate ein- und ausgeschaltet werden DynamicResource s verwenden). Das Endergebnis funktioniert ein wenig wie CSS-Panels auf einer Website, bei der der gesamte Inhalt auf der Seite vorhanden ist, aber nicht der gesamte Inhalt ständig sichtbar ist. ControlTemplate s sind dafür magisch und ich möchte, dass ihre Fähigkeiten in Shell erhalten bleiben.

@dansiegel Ich würde es einfach codieren, um eine andere Shell zu laden, je nachdem, ob die App auf einem Telefon oder einem Tablet/Laptop/Desktop ausgeführt wird.

@jsiemens das ist in Ordnung, mein Kommentar soll nur weitere Gespräche und kritisches Denken

@dansiegel Ja, ich glaube, ich

Ich nehme an, es ist nicht ganz auf Thema für diese Spezifikation, aber ich erwähnte es hier , weil wir reden darüber , wie komplexe Layouts zu konstruieren (zB @MelbourneDeveloper ‚s 3. Priorität -. Flexibilität), und dies ist ein sicherlich ein Layout , das die Spitze der mind für mich und mein Team (wir erstellen eine Karten-App, bei der wir Inhaltsfelder über der Karte schweben lassen möchten, die "Nur-Seiten-Inhalte" wie Navigationsseiten und Registerkarten enthalten können).

Ich weiß nicht, wie dies mit Shell gelöst werden würde, aber meine erste Reaktion auf Shell ist, dass es nichts zu tun scheint, was ich nicht bereits tun kann. Ich habe im Allgemeinen das Gefühl, dass das Xamarin Forms-Team weiterhin Funktionen entwickelt, mit denen ich Dinge tun kann, die ich bereits tun konnte, aber nur auf andere Weise (z. B. CSS, Visual State Manager und jetzt die Zeichnungs- und Shell-Spezifikationen). Das bringt mir also nicht viel Wert. Ich hätte lieber neue Funktionen, die es mir ermöglichen, Dinge zu tun, die ich vorher nicht konnte (außerhalb benutzerdefinierter Steuerelemente und/oder Renderer). Wenn Shell die Antwort ist, um dies zu erreichen, weil die Syntax eleganter ist, dann bin ich dafür, aber letztendlich möchte ich, dass sie leistungsfähiger und ausdrucksstärker ist als die aktuelle Page/View-Hierarchie, da sie wirklich Wert ist.

Könnten Sie die Erstellung einer nativen Ansicht pro xamarin-Ansicht entkoppeln, wenn alle Unteransichten in einem Layout ohne Verwendung nativer Widgets gerendert werden können? Eine Art automatischer Hybrid-Flatter/Xamarin-Ansatz, bei dem Gruppen von XF-Ansichten auf einer einzigen Oberfläche gerendert und nur auf eine native Ansicht ausgeblendet werden. Es wäre sinnvoll, die Android-Ansichtserstellung/das Layout c# -> Java-Interop-Kosten zu vermeiden.

im Gange!!

@jassmith, nachdem die Shell fertig ist, ist die Ziehung zusammen gültig?

Wird die Shell Macos und WPF unterstützen?

@juepiezhongren die ersten Ziele sind iOS und Android. Danach werden andere Plattformen priorisiert.

Zeichnung wird derzeit nicht entwickelt. In seiner aktuellen Spezifikation wäre es mit Shell gültig. Genau wie heute können Sie SkiaSharp- und Skia-basierte Steuerelemente in Xamarin.Forms verwenden.

Wir arbeiten an anderen nativen Strategien, um ein konsistentes Design für Materialien und andere Designstile zu unterstützen.

@davidortinau Macht die Shell die RTL-Unterstützung besser?

Auf welche Weise besser? Was fehlt dir heute beim RTL-Support? Wir sollten es überall ansprechen.

Um ehrlich zu sein, habe ich schon länger keine XF-Entwicklung gemacht, aber die meisten Einschränkungen sind bekannt: Schauen Sie sich #1222 und #2448 an

Vielleicht kann Shell bei diesen allgemeinen Einschränkungen helfen:

  • Die Position der Schaltfläche NavigationPage, die Position der Symbolleistenelemente und die Übergangsanimation werden derzeit vom Gebietsschema des Geräts und nicht von der FlowDirection-Einstellung gesteuert.
  • Globale App-Einstellung für FlowDirection

Und einige andere plattformspezifische Einschränkungen

Wichtigstes Feature von Xamarin.Forms. Es hätte in erster Linie so gebaut werden sollen.

ohne zeichnung fehlt xf noch einiges

@juepiezhongren

Verwenden Sie einfach Skiasharp

@mackayn ich habe es
https://github.com/xamarin/Xamarin.Forms/issues/1789
universelles Aussehen ist ein Muss

adam ging zum flattern, es ist wirklich ein trauriges zeichen für xf, wo xamarin ursprünglich eher leicht einen viel besseren ruf erreichen konnte

xamarin.native ist für xf viel solider als alle anderen plattformübergreifenden Lösungen, egal was nativ oder flattern reagiert. Als Dotnet-Liebhaber ist die aktuelle Situation von xf für mich immer etwas enttäuschend.

@juepiezhongren

Diese Diskussion ist sinnlos, wenn sie nicht Ihren Anforderungen entspricht, verwenden Sie Flutter. Sie ermöglicht es uns, Apps auf mehreren Plattformen bereitzustellen (iOS und Android nur mit Flutter usw.). Diese Änderungen machen ein einheitliches Erscheinungsbild leichter erreichbar.

einfache kleine meckern, einfach so viel. Immer noch ein Hurra für Shell!

Ich würde zustimmen, dass es schöner wäre, Skia viel mehr in die Forms-API zu integrieren (wie es Telerik getan hat). Ich stimme zu.

Ich bin froh, dass sie die Mühe in Shell & CollectionView investieren.

Hallo, bitte sagen Sie alle, wie kann ich das Flayout in rechts für rechts nach links verwenden.

Hi,

Ich liebe die Idee, aber ich habe nur ein paar kleine Inputs.
Ich schätze, ich bin etwas spät dran, aber die Namensgebung ist etwas verwirrend, denke ich.

  1. Item, Section und Content sind allesamt sehr allgemeine Namen. In welchem ​​Verhältnis diese stehen, ist nicht sofort klar. Ist es Inhalt => Abschnitt => Artikel oder Abschnitt => Inhalt => Artikel oder Artikel => Abschnitt => Inhalt.
    So können wir vielleicht etwas genauer spezifizieren, was die verschiedenen "Dinge" sind, indem wir einen genaueren Namen finden.

  2. Das führt mich zum nächsten Eingang. Wir haben eine Shell als Behälter für alle inneren Gegenstände. Können wir also nicht einfach einfache Namen wie "Item" anstelle von "ShellItem" verwenden. Es sieht für mich etwas unnötig aus, alle "Dinge" Shelltem, ShellSection etc. zu nennen aber ok. das lässt sich streiten.

Autsch

Wird es noch 2018 erscheinen?

Wir haben JETZT eine Vorschauversion verfügbar! Werfen Sie einen Blick auf https://blog.xamarin.com/connect-2018-xamarin-announcements/ für einige großartige Beispiele.

Brauchen wir wirklich Android 9? Das scheint eine kleine Einschränkung zu sein.

Das klingt alles ziemlich gut, scheint aber ausschließlich auf der UI-Interaktion zu basieren.
Ich denke, ich werde es herausfinden, wenn ich es versuche, aber meine anfängliche Sorge ist, wie ich die Navigation von Geschäftslogik oder Code aus steuern kann, z.

@hassanrahimi

Hallo, bitte sagen Sie alle, wie kann ich das Flayout in rechts für rechts nach links verwenden.

Während RTL unterstützt wird, erscheint das Flyout-Menü weiterhin auf der linken Seite. Dies ist eine aktuelle Einschränkung.

Ist es möglich, die Benutzeroberfläche der unteren Tabbar anzupassen?

Ist es möglich, der Shell Steuerelemente hinzuzufügen, die beim Navigieren in der Shell nicht neu geladen werden? Zum Beispiel ein FAB..

Die Benutzeroberfläche der unteren Registerkartenleiste von @stfnilsson kann über Stile und dann einen benutzerdefinierten Renderer angepasst werden. Wir werden in Zukunft Beispiele liefern.

Für MaterialShell ist geplant, Steuerelemente hinzuzufügen, die wie von Ihnen beschrieben global sind. Können Sie zusätzlich zu FAB weitere Szenarien bereitstellen, die davon profitieren würden?

Erstens: Ich habe schon früher meine eigene Shell verwendet, jetzt kann ich meine eigene einfach durch deine ersetzen und es ist viel besser. Ich mag es wirklich.

Wahrscheinlich sind meine Fälle benutzerdefiniert und haben nichts mit Shell zu tun, aber:

Fall eins:
Wenn ich eine App mit einem sehr benutzerdefinierten Menü erstellen möchte, eine Menüschaltfläche in jeder Ecke der App, wie füge ich die Schaltflächen hinzu, damit sie Teil der Shell sind (wie Overlay oder Billboard). Ich möchte nicht, dass es jedes Mal neu gerendert wird, wenn ich navigiere.

Fall zwei:
Ich möchte die Shell verwenden, aber die untere Tableiste so anpassen, dass die mittlere Schaltfläche höher ist (genannt mittlerer erhöhter Button). Sollte ich den Renderer verwenden und die untere Navigationsansicht anpassen?

Meinst du, ich sollte die Shell für spezielle Fälle wie diesen verwenden?

Natürlich überlege ich, dies auf jeder Plattform zu tun, aber die Menüs sollten auf allen Plattformen gleich aussehen, also möchte ich den Code teilen.

Hier ist mein Feedback. Ich mache diesen Test ( 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>

Alles funktioniert, wenn wir auf das Hamburger-Menü tippen. Wenn wir jedoch zum Menü Test und auf Home und Notifications hin und her tippen und zwischen Recent oder Settings wählen, wird die Seite wird jeweils geöffnet. Aber wenn wir dann erneut auf das Hamburger-Menü tippen, stürzt die App ab.

image

Wie können wir GroupHeaderTemplate verwenden , um einen Titel für eine Gruppe von ShellContent in einem ShellItem anzuzeigen?

Vielen Benutzern ist klar, dass Xamarin Forms in seiner aktuellen Größe und Komplexität nicht gewartet werden kann. Daher sollte alles Neue die Komplexität verringern, anstatt sie zu erhöhen.

@jassmith Die Absicht ist, dass es dir NIE besser geht, ohne Shell zu sein. ... Die Absicht ist sicherzustellen, dass die Shell-Renderer tatsächlich einfach zu konfigurieren und vernünftig sind.

Wenn Shell abgeschlossen ist, was kann in Zukunft abgeschrieben werden, und wenn dies erledigt ist, wird die Gesamtkomplexität von Xamarin Forms reduziert? Werden alle anderen Seiten außer ContentPage abgeschrieben?

Die Strategie sollte sein, so viel wie möglich aus dem Repo herauszuholen. Die Stabilität und Wartbarkeit des Core Repos ist das Wichtigste.

Auch wenn es einen Grund gibt, warum Shell nicht ShellPage heißt? Andere Page-Klassen haben Namen, die auf "Page" enden.

Die aktuelle Anzeige für Shell (in https://blog.xamarin.com/xamarin-forms-4-0-preview/ ) ist nicht vielversprechend.

  1. Eine vereinfachte Möglichkeit, das hohe Niveau Ihrer Anwendungsarchitektur auszudrücken

Dies führt Xamarin über seinen eigentlichen Zweck hinaus. Xamarin wird für die Anwendungsarchitektur nicht benötigt. Hier sollte es nur um das Layout gehen.

  1. Eine Hierarchie gängiger UI-Navigationsmuster, die zu Ihren mobilen Zielplattformen passen

Ich hoffe, "mobile" ist hier ein Druckfehler, da Xamarin.Forms auch Desktops abdeckt.

  1. Ein robuster Navigationsdienst

Xamarin.Forms benötigt keine Navigation. Wenn die aktuelle Navigation nicht funktioniert, kann sie einfach abgeschrieben werden, da es viele gute Ansätze für die Navigation gibt, für die nichts eingebaut werden muss.

Hallo @charlesroddie , danke für das Feedback.

Es hört sich so an, als ob Shell derzeit nicht das Richtige für Sie ist, und das ist in Ordnung. Sie müssen Shell nicht verwenden, wenn es Ihren Apps keinen Mehrwert bietet. Die Shell-Spezifikation wird jedoch stark von Entwickler-Feedback beeinflusst, und der Dienst an unserer Entwickler-Community ist der Kern unseres Ziels.

In Xamarin.Forms beschreiben Sie heute bereits Ihre Anwendungsarchitektur, die Inhaltshierarchie, mit TabbedPage, MasterDetailPage, mit Registerkarten und Menüelementen und verschiedenen Kombinationen. Das meine ich hier mit "Architektur". Shell vereinfacht und ersetzt diese Muster (wenn Sie Shell verwenden).

"Mobile" ist kein Druckfehler und wird sehr bewusst verwendet. Shell ist auf iOS und Android ausgerichtet. Wenn Sie auf Desktops abzielen, verwenden Sie Shell nicht. Ich habe von Mitwirkenden Interesse an dem Hinzufügen von Shell-Unterstützung zu den Desktop-Backends gehört, und diese PRs würden gut aufgenommen. Ich glaube, Shell ist sehr gut positioniert, um Apps auf jede Plattform zu bringen und flexibel (widerstandsfähig) zu sein, um sich selbst an radikale UI-Musteränderungen anzupassen (wer weiß, was zukünftige Schnittstellen annehmen werden). Heute ist das Testgelände iOS und Android.

Als wir mit Entwicklern über Shell gesprochen haben, war ich überrascht zu erfahren, dass die Shell-Navigation ganz oben auf der Liste der von ihnen geschätzten Funktionen steht. Das Routing, Deep Linking, die Möglichkeit, die Navigation zu unterbrechen, den Backstack sofort zu beschreiben, Daten zu übergeben und das langsame Laden von Seiten sind sehr überzeugende Attribute für Entwickler, die Probleme lösen, mit denen sie heute konfrontiert sind.

Wenn Sie auf Desktops abzielen, werden Sie Shell nicht verwenden... Ich glaube, Shell ist sehr gut positioniert, um Apps auf jede Plattform zu bringen

Ich möchte nur nicht, dass Xamarin unter seinem eigenen Gewicht zusammenbricht. Bis Shell alle Plattformen erreicht hat man ein Wartungsproblem, da es sich dann um eine Ergänzung, nicht um einen Ersatz für andere Seiten handelt. Sie haben auch ein Messaging-Problem für Desktop-Entwickler, zu einer Zeit, in der viele offensichtlich ein plattformübergreifendes Framework einführen möchten.

Xamarin zeigt viel Feature Creep, zB CSS. Dies könnte das gesamte Projekt gefährden und ich hoffe, dass einige Entscheidungsträger in der Organisation dies verstehen.

Ich möchte nur nicht, dass Xamarin unter seinem eigenen Gewicht zusammenbricht. Bis Shell alle Plattformen erreicht hat man ein Wartungsproblem, da es sich dann um eine Ergänzung, nicht um einen Ersatz für andere Seiten handelt. Sie haben auch ein Messaging-Problem für Desktop-Entwickler, zu einer Zeit, in der viele offensichtlich ein plattformübergreifendes Framework einführen möchten.

Xamarin zeigt viel Feature Creep, zB CSS. Dies könnte das gesamte Projekt gefährden und ich hoffe, dass einige Entscheidungsträger in der Organisation dies verstehen.

Ich stimme zu. Wenn eine Funktion auf dem Desktop (UWP) nicht unterstützt wird, nützt sie uns nichts. Ich stimme auch in Bezug auf CSS zu - es scheint eine Menge zusätzlicher Komplexität und Wartungsaufwand für eine Funktion zu sein, die mir nichts erlaubt, was ich vorher nicht tun konnte. Was wir viel mehr als alles andere brauchen, sind einfach mehr Kontrollen – für alle Plattformen und mehr Möglichkeiten für bestehende Kontrollen. Shell hat immer noch dieselben Einschränkungen wie die Page-Infrastruktur, da Sie sie vollständig übernehmen müssen oder sie überhaupt nicht verwenden können und sie nur auf der Stammebene Ihrer Anwendung leben kann. Und nicht nur das, Sie haben jetzt zwei Möglichkeiten, dasselbe zu tun, und es ist kompliziert und verwirrend. Wenn ich also nur ein Flyout-Menü ohne Shell haben möchte, kann ich das nicht tun. Und die Anzahl der Steuerelemente, denen die Shell-Elemente zugeordnet werden, ist extrem begrenzt - Registerkarten, Navigationsseiten und Flyouts reichen uns nicht aus. Wenn Xamarin Forms die Bandbreite an Steuerelementen bieten könnte, die ein Framework wie UWP hat, als eine Reihe von Steuerelementen bereitgestellt, genau wie in UWP, und ohne die nutzlose Aufblähung (z. B. CSS), wäre ich glücklich.

Ich denke, Sie sprechen einige gültige Punkte an, aber als jemand, der eine UWP/iOS/Android-App verwaltet und etwas enttäuscht war, als ich erfuhr, dass Shell UWP nicht unterstützt, mit nur einem "vielleicht" in der Zukunft. Dann wurde mir klar, dass ich den Sinn von Shell vermisse. Es ist eine großartige einfache Möglichkeit für jemanden, eine App für die beiden primären mobilen Plattformen zu erstellen. Als Unternehmensentwickler ... brauche ich UWP, ich habe gewartet, bis es UWP-Unterstützung gab, um XF überhaupt in Betracht zu ziehen ... aber ich vermute, viele Entwickler brauchen es nicht ... Ich brauche auch eine viel komplexere Navigation usw Shell bietet.

Aber ich erinnere mich auch, dass ich viel Zeit damit verbracht habe, mit der Navigation und den Seiten zu beginnen ... was einige Zeit dauern kann, um es herauszufinden. Aber ich erstelle auch eine sehr komplexe Branchen-App, es gibt Tonnen von einfachen Apps, die einfach nicht so komplex sind. XF muss sich weiterentwickeln, um gegen Dinge wie Flutter usw. zu bestehen. Es muss auch ständig neue Entwickler dazu bringen, es zu übernehmen. Und es scheint mir, dass die Nutzung der Plattform dazu beitragen wird, die für die Wartung der Plattform erforderlichen Ressourcen zu sichern.

Ich habe auch ein paar zukünftige Projekte, bei denen ich kein UWP benötige, und ich freue mich darauf, Shell für sie zu verwenden, weil ich denke, dass es so viel schneller für mich sein wird, sie zu produzieren.

Ich benutze XF erst seit der Veröffentlichung 2.3 und obwohl es sicherlich noch mehr zu tun gibt... hat sich die Plattform, wie sie jetzt existiert, stark stabilisiert...zumindest für mich... die zusätzliche Wartung und historisch scheint es mir, dass das XF-Team sich des Wartungsaufwands sehr bewusst ist ... also vertraue ich darauf, dass sie ihn unter Kontrolle haben.

Danke für die tolle Ergänzung der Plattform!

Das Hinzufügen neuer Vorgehensweisen wird neue Entwickler verwirren, bis die alten Methoden abgewertet und die alten Dokumente entfernt werden.

Flattern ist viel einfacher. Keine Auszeichnungssprache, alles im Code. Xamarin wird nicht konkurrieren, indem es komplexer und fehlerhafter wird. Es wird konkurrieren, indem es mehr als Flutter (mehr Plattformen) mit dem gleichen Fokus tut.

Es kommt zu dem Punkt, an dem wir einen Xamarin.Core benötigen, ohne XAML oder CSS oder Eigenschaftsbindungen, ohne Pages oder Shells über die Basisklassen hinaus, mit einem Fokus auf Leistung und Stabilität für diesen Core. Wenn einige Entwickler diese Features auf Kosten der aktuellen Fehlerrate akzeptieren möchten, können sie Xamarin.Extensions verwenden, in denen all diese Dinge leben würden.

Das Hinzufügen neuer Vorgehensweisen wird neue Entwickler verwirren, bis die alten Methoden abgewertet und die alten Dokumente entfernt werden.

Flattern ist viel einfacher. Keine Auszeichnungssprache, alles im Code. Xamarin wird nicht konkurrieren, indem es komplexer und fehlerhafter wird. Es wird konkurrieren, indem es mehr als Flutter (mehr Plattformen) mit dem gleichen Fokus tut.

Es kommt zu dem Punkt, an dem wir einen Xamarin.Core benötigen, ohne XAML oder CSS oder Eigenschaftsbindungen, ohne Pages oder Shells über die Basisklassen hinaus, mit einem Fokus auf Leistung und Stabilität für diesen Core. Wenn einige Entwickler diese Features auf Kosten der aktuellen Fehlerrate akzeptieren möchten, können sie Xamarin.Extensions verwenden, in denen all diese Dinge leben würden.

@charlesroddie Nichts, was sie oben getan haben, ist, dass Sie gezwungen sind, XAML zu verwenden. XAML in Xamarin.Forms ist optional - war es schon immer. Ich mache meine Xamarin.Forms-Apps-UIs immer nur mit Code – jedes "Tag", das Sie oben sehen, ist eine Klasse, die instatisiert und dem entsprechenden übergeordneten Element hinzugefügt werden kann.
Wenn mit Xamarin.Forms keine codierten Benutzeroberflächen möglich wären, würde ich es nicht verwenden - Punkt!

Zu Flutter im Allgemeinen - es ist sehr schön, aber das Problem ist nur iOS und Android - das funktioniert bei mir auch nicht, da ich auf macOS, Windows 7/8.1 und Linux abzielen muss. Nichts schlägt Xamarin.Forms in dieser Hinsicht!

Kann ich die benutzerdefinierte Ansicht als Masterseite festlegen, ist dies sehr wichtig, wir bevorzugen nicht nur MenuItem oder Seiten?

Xamarin Mac- und UWP-Unterstützung?

Wie würden Sie sich in den Navigationsprozess einklinken? Ich nehme an, Sie wissen das, aber wenn Sie zum Beispiel Prism nehmen, werden Ansichtsmodelle von einem DI-Container erstellt und automatisch als BindingContext für die angeforderte Seite festgelegt.

Sie könnten auch INavigatedAware für ein Ansichtsmodell implementieren und bestimmte Anwendungsfälle wie das Laden von Daten, das Aktivieren/Deaktivieren von Diensten usw. behandeln.

Ich wollte etwas Ähnliches hinzufügen, also war meine erste Vermutung das Shell-Ereignis OnNavigating und OnNavigated , aber Current und Target machen kein ShellItem verfügbar, daher ist es nicht möglich BindingContext nach Konvention festlegen oder Ansichtsmodellereignisse auslösen?

Irgendwelche Vorschläge dazu?

BEARBEITEN: Von #5166 verfolgt.

Ist es für die Icons in dieser Shell möglich, "Icon Font" anstelle eines Bildes zu verwenden? Es ist schwierig, die Farbe während der Laufzeit für Bilder zu ändern, und es ist auch schwierig, sie für verschiedene Auflösungen auf verschiedenen Plattformen zu verwalten. Kann ich vorschlagen, eine Symbolklasse mit der Material Design-Schriftart zu erstellen, die mit der SkiaSharp-Bibliothek gerendert wird? Die Klasse ist relativ einfach und macht viele Symbole für die Shell bereit.

@vincentwx Ich stimme zu. Icon-Schriften sind so viel einfacher zu verwenden und auch vertraut.

@vincentwx @stevehurcombe absolut. Ich mache das gerade in einer App:

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

Ich habe dies verwendet, um eine statische Klasse aller Glyphen zu erstellen: https://andreinitescu.github.io/IconFont2Code/

Es gibt einen Fehler mit der iOS-Farbe, der behoben werden muss. #5071

Xamarin Mac- und UWP-Unterstützung?

Derzeit nicht @mdonogma. Wir sammeln Interesse/Nachfrage für die Unterstützung zusätzlicher Plattformen, aber derzeit ist dies nicht auf unserer Roadmap.

@davidortinau Danke für den Code und Link.

In Android 8.0 kann ich die Webseite nicht im WebView Element scrollen, das in Shell-Inhalt gehostet wird. Aber ohne Xamarin Shell funktioniert es einwandfrei.

Xamarin-Formular 4.0.0.135214-pre4

Gibt es eine einfache Möglichkeit, die FontFamily der unteren Registerkarten und die Titelansicht zu ändern?

@varyamereon Das habe ich gestern gemacht. Erweitern Sie die Shell, um FontFamily setzen zu können.
Ich werde meine erweiterte Shell bald auf GitHub veröffentlichen, aber:

Erstellen Sie eine benutzerdefinierte Shell:

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

Erstellen Sie dann einen benutzerdefinierten Shell-Renderer:

[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
            };
        }

Dann:

 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()
{
{

Dann um die Schriftfamilie einzustellen: _(mach es nicht zu oft)_

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

Wer hat die Shell mit Unterstützung für ein Popup von unten erweitert (unteres Blatt)?

Ich habe viel Code von meiner eigenen alten Shell in die neue verschoben (Komposition natürlich), ich mag es wirklich. Ich benutze es sogar für eine App, die im Mai veröffentlicht wird :-) (Ich debugge sogar den Xamarin-Code)

Gibt es Unterstützung, um eine Liste an die Shell.MenuItems zu binden? Oder sollte ich BindableLayout verwenden? Manchmal muss ich eine Liste aus der Datenbank laden und diese als Menüs verwenden. Sie haben dieselbe Ansicht, laden jedoch je nach ausgewähltem Menü unterschiedliche Daten.

Gibt es eine Möglichkeit, das OffscreenPageLimit in Android bei Verwendung der Shell zu ändern? Dies ist leider sehr wichtig für meine App und hindert mich daran, mit Shell weiterzumachen.

Vielen Dank!

Ein paar Feature-Anfragen:

  1. Legen Sie auf Shell-Ebene die FontFamily für alle Seitentitel fest.
    z.B

  2. Legen Sie auf Shell-Ebene das Titel-/Nav-Hintergrundbild für alle Seitentitel/Navigationsleisten usw. fest.
    z.B

GroupBehavior funktioniert bei mir in pre4 nicht:

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

xxx/Shell/Shell.xaml(14,14): Fehler: Position 108:14. Keine Eigenschaft, bindbare Eigenschaft oder Ereignis für "GroupBehavior" gefunden, oder der Typ zwischen Wert und Eigenschaft stimmt nicht überein.

und GroupHeaderTemplate scheint nichts zu tun, aber nicht sicher, wie es verwendet oder aktiviert wird.

Ich versuche, MenuItems hinzuzufügen/zu entfernen, wodurch Elemente erfolgreich über MenuItems.Add(item) hinzugefügt werden, aber es wird kein Ergebnis angezeigt, wenn das Flyout erneut angezeigt wird. Ist das der richtige Ansatz dafür?

Ich sehe keine Erwähnung der Manipulation von MenuItems, aber die Shell ist für mich ziemlich nutzlos (und ich denke, viele andere, einschließlich @puppetSpace oben), es sei denn, diese Elemente können basierend auf Ihrer Geschäftslogik dynamisch verwaltet werden.

Ich würde dbwelch zustimmen, dass es sehr wichtig ist, die Shell in der cs-Datei programmgesteuert ändern zu können. Nicht nur für Menüpunkte, sondern auch ShellItems & ShellSections.

Wenn ich Flyout einschalte und Menüelemente hinzufüge, erhalte ich in Android ein Hamburger-Menü, und in iOS funktioniert es, wenn ich auf diese Stelle klicke, es gibt jedoch kein Symbol. Irgendwelche Ideen?

@KyleTraynor dafür gibt es irgendwo ein offenes Problem. Sie müssen die Bilder 3bar.png und [email protected] manuell in Ihren iOS-Ressourcenordner kopieren und

Die Bilder, die ich in der Quelle gefunden habe, sind angehängt:
3bar 2x
3bar

@melucas Danke für die Hilfe! Ich wurde verrückt, als ich versuchte, das zu beheben. Funktioniert super.

Weißt du zufällig, wie ich das OffscreenPageLimit für Android einstellen kann, wenn ich Shell verwende?

Ich habe Top-Tab-Seiten, die mit 4 ShellContents in 1 ShellSection erstellt wurden, und es funktioniert hervorragend unter iOS, aber auf Android werden die Seiten neu geladen, wenn zwischen ihnen gewechselt wird, was ich nicht möchte. Normalerweise könnte ich mit meiner eigenen Registerkartenseite das OffscreenPageLimit setzen, um dieses Problem zu beheben, aber ich finde keine Möglichkeit, dies mit Shell zu tun.

@davidortinau könnten wir die Option haben, die Schriftfamilie auf festzulegen ? In jedem Projekt muss ich benutzerdefinierte Renderer für iOS und Android erstellen, um Schriftarten zu ändern.

Angesichts der Tatsache, dass auf meinen Beitrag über die Möglichkeit, die Elemente in der Flyout-Shell tatsächlich zu ändern, keine Reaktion erfolgt ist, ist diese Funktionalität möglicherweise nicht im Umfang enthalten oder wird möglicherweise als Fehler angesehen?

Ich bin mir nicht sicher, wie eine seriöse App diese Shell ohne diese Funktionalität verwenden kann. Nur sehr einfache Apps erfordern keine Möglichkeit zum Hinzufügen/Ändern/Entfernen/Deaktivieren von Elementen in ihren Menüs basierend auf entweder a) dem Kontext des Benutzers (dh authentifiziert/nicht authentifiziert) oder b) unterschiedlichen Zuständen der Anwendung, die dies tun würde benötige es.

Nur neugierig @jassmith , sind die Leute, die die Spezifikation erstellt haben, in dieses Forum

Übrigens, abgesehen von diesem einen wichtigen Punkt habe ich die Shell in meinen Code für eine App implementiert und sie funktioniert sehr gut, danke! Aber leider muss ich es herausziehen und mein eigenes Flyout implementieren, wenn die Shell diese Funktionalität nicht hat.

@dbwelch , ein paar Dinge.
Sie posten in der Spezifikation, daher werden Sie wahrscheinlich keine Antwort erhalten, wie Sie sie beim Öffnen einer neuen Ausgabe geschrieben haben. Außerdem arbeitet Jason nicht mehr an Forms, also ist es irgendwie sinnlos, ihn anzurufen.

Unterm Strich ein Problem melden

@dbwelch @ChaseFlorell Ich habe hier ein Problem eröffnet: https://github.com/xamarin/Xamarin.Forms/issues/5428

@davidortinau könnten wir die Option haben, die Schriftfamilie auf festzulegen ? In jedem Projekt muss ich benutzerdefinierte Renderer für iOS und Android erstellen, um Schriftarten zu ändern.

@jamiewest Senden Sie eine Funktionsanfrage! Vielen Dank! 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

Könnte die UseSwipeGesture-Funktion implementiert werden?
Es scheint, als hätte die ShellItem-Klasse jetzt nicht die ShellAppearance-Eigenschaft für Opera.
Aber jetzt in Android sind die Tabs der Shell nicht wie die TabPage (TabPage kann standardmäßig wischen.)

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

@jingliancui , Bruder Cui, gibt es QQ oder WeChat?

@juepiezhongren Hallo, du kannst dieser qq-Gruppe beitreten, um mit mir zu chatten 313308215

Werden Shell und visuelle Unterstützung für UWP auf RTM kommen?

Ich begrüße diese Idee - egal, was sie erschwert, denn die Arbeit mit Navigationsseiten, Master-Detail-Seiten usw. fühlt sich viel zu umständlich an. Vielleicht liegt das daran, dass ich einen Webhintergrund habe (habe nicht viel mit nativen APIs gearbeitet). Das Anpassen der Navigationsleiste, der Seitentitel, der Zurück-Schaltfläche, der Symbolleistenelemente, der Kopf- und Fußzeilen (ListView) usw. fällt hier ein.

Ich vermute, was ich verlange, ist, dass neue Funktionen wie *Shell unter Berücksichtigung von Anpassung und Erweiterbarkeit ausgeliefert werden. Es gibt nur sehr wenige Situationen, in denen wir nicht eine Reihe von Renderern, Verhalten, Triggern usw. erstellen mussten, um scheinbar einfache Dinge auszuführen.

Was auch immer Sie sich einfallen lassen, tun Sie bitte alles, um es uns zu erleichtern, unsere Xamarin.Forms-Apps so gut wie andere native Apps aussehen zu lassen! Es hört sich so an, als würde uns diese Funktion ein besseres Launchpad für modern aussehende XForms-Apps bieten!

Gibt es Quellcode, der verfügbar ist, um zu sehen, wie diese Shell funktioniert, anstatt in der Spezifikation herumraten zu müssen? Welcher Stil wird beispielsweise verwendet, um das Hamburger-Symbol einzufärben, falls verfügbar. Sorry, neu bei C#/Xamarin, aber wenn der Code irgendwo sichtbar wäre, würde das enorm helfen.

@dbwelch Sie können den Quellcode direkt hier auf GitHub durchsuchen. Drücken Sie "T" und geben Sie Shell ein, um die zugehörigen Klassen anzuzeigen. Dies ist jedoch möglicherweise nicht der beste Ausgangspunkt, wenn Sie C#/Xamarin noch nicht kennen. Ich empfehle, einige meiner Beispiele zu überprüfen, bis wir mehr Dokumentation haben:

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

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

@davidortinau danke, aber ich dachte, es wäre nur veröffentlichter Code, der verfügbar ist, wo ist der Shell-Code? Ich habe unter Branches nach 4.0, Shell und anderen gesucht, aber es versteckt sich vor mir! Vielen Dank!

@pauldipietro Danke, jetzt sehen. @davidortinau Ich habe tatsächlich viel Zeit mit allen Links verbracht (außer LittleThings, die ich gerade heruntergeladen habe), aber ich sehe einfach nicht, wie man so etwas wie die Hamburger-Symbolfarbe ändern kann. Es wird in meiner App als lila angezeigt, aber ich habe nirgendwo eine lila Farbe definiert (die ich sehen kann). Ein bisschen frustrierend ;-).

UPDATE: Ich habe das Problem gerade gefunden, und natürlich ist es ein ekliger Code, der im FinishedLaunching vorhanden ist, um TintColor hinzuzufügen. DOH!

Danke Herren, schätzen die Hilfe!

Ich habe einige Elemente, die im Flyout-Bedienfeld angezeigt werden, was in Ordnung ist. Derzeit gibt es jedoch bereits eine Möglichkeit, ein Shell-Element (nicht den Elementinhalt) auszublenden/nicht anzuzeigen. Beispiel, ich habe eine ContentPage und möchte nur die Navigation in der Shell haben.

<local:DetailPage />

Es scheint, dass das Element immer im Flyout-Bedienfeld / in der Liste hinzugefügt wird. Und wenn kein Titel vorhanden ist, hat es einen leeren Stapel/Platzhalter des Elements. Ich habe viele Möglichkeiten ausprobiert, den Gegenstand zu verstecken, immer noch kein Glück. Wahrscheinlich kann jemand helfen oder das Feature ist noch nicht verfügbar.

Vorwort: Ich bin ein neuer Geldautomat. Versuchen nicht zu sein.

@davidortinau Also, ich habe versucht, dieses Shell-Feature zu lernen, um Navigation usw. in unser erstes Xamarin.Forms-Projekt für unser Unternehmen (woot!) oder mehr Parameter von einem ShellItem zu anderen Teilen der Anwendung über die neue Routing-Funktionalität. Ist das überhaupt ein Ding? Oder müssen wir stattdessen beim Befehlen mit MenuItems innerhalb einer MenuItem-Sammlung bleiben? Wenn wir ein MenuItem verwenden müssen, um einen oder mehrere Werte aus der Flyout-Ebene zu übergeben, können wir unsere App anscheinend nicht mehr mit der Shell-Hierarchie strukturieren, da wir stattdessen MenuItems verwenden? Verlieren wir das nicht, wenn wir MenuItems mit Befehlsparametern verwenden?

Gibt es jemanden, der sich darauf einklinken kann? Wenn ja, würde ich mich sehr darüber freuen. Grundsätzlich würde ich gerne Shell verwenden, aber immer noch in der Lage sein, das ShellItem zu markieren, das der Benutzer beim Klicken auf eines ausgewählt hat, um es an eine ContentTemplate-Seite oder was auch immer angemessen zu übergeben, da viele der ShellItems zu einer ähnlichen Zwischenseite navigieren, um einen Bestelltyp zu erstellen und OrderDepartment Dropdown-Auswahl, bevor Sie zum Hauptbildschirm Order mit den entsprechenden Daten für den richtigen Typ und die richtige Abteilung gehen.

Außerdem entschuldige ich mich, wenn dies der falsche Ort dafür ist. Wenn ja, zeige mich bitte an der richtigen Stelle. Vielen Dank!

Aktualisieren:
Vielleicht verwende ich vorerst einfach die MenuItems und übergebe einen Befehlsparameter an ein ShellViewModel, um mit den richtigen Werten für die Zielseite zu navigieren. Jetzt, wo ich darüber nachdenke, muss ich wirklich nicht mehr zu einer Struktur mit Registerkarten von diesen MenuItems navigieren, die auf die ContentTemplate-Seite schieben.

Ich habe mich auch gefragt, ob wir definieren können, wo sich MenuItems innerhalb des Flyouts befinden, damit die ShellItems nicht alle nach oben springen; und wenn wir eines Tages unsere MenuItems nicht als Teil einer Sammlung definieren müssen, damit sie sich mit ShellItems vermischen können wie:
MenuItem
ShellItem
ShellItem
MenuItem
ShellItem
MenuItem
...
Das, oder ShellItems einfach in die Lage versetzen, Parameter zu einem bestimmten Zeitpunkt zu übergeben, wenn dies nicht bereits möglich ist.

Ich bin bei @anthcool und finde das ein extrem wichtiges Feature. Ich konnte keine Möglichkeit finden, dies zu tun, und musste die Verwendung von Shell einstellen. Sie müssen nur in der Lage sein, etwas an eine Inhaltsseite weiterzugeben, um zu wissen, auf welche Seite geklickt wurde.

@anthcool versuche nur zu helfen und gebe hier einen Vorschlag, wie ich es im Moment getan habe. Erstellen Sie eine Navigationsparameterklasse, die ein readonly Stack<NavigationParameter> als Stapelliste hat, dh

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

Der Navigationsparameter ist:

public class NavigationParameter : NameValueCollection { }

Sie können beim Navigieren Parameter vor dem Push hinzufügen, z. B.:

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

Sobald Sie auf der anderen Seite sind, können Sie den Wert einfach anzeigen oder anzeigen und den Schlüssel überprüfen.
Etwas wie oben. Ich hoffe, das hilft.

@anthcool versuche nur zu helfen und gebe hier einen Vorschlag, wie ich es im Moment getan habe. Erstellen Sie eine Navigationsparameterklasse, die ein readonly Stack<NavigationParameter> als Stapelliste hat, dh

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

Der Navigationsparameter ist:

public class NavigationParameter : NameValueCollection { }

Sie können beim Navigieren Parameter vor dem Push hinzufügen, z. B.:

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

Sobald Sie auf der anderen Seite sind, können Sie den Wert einfach anzeigen oder anzeigen und den Schlüssel überprüfen.
Etwas wie oben. Ich hoffe, das hilft.

Danke für die Idee @rizamarhaban! Ich weiß es wirklich zu schätzen, dass Sie sich darauf eingelassen haben. Dankeschön! Ich werde das demnächst hier überprüfen. Nochmals, schätzen Sie es!

Sehr enttäuscht zu erfahren, dass Shell und Visual UWP nicht unterstützen.

Ist diese Spezifikation wirklich fertig?
Warum das schließen, nur weil es jetzt eine Tizen-Implementierung gibt?
Ich hatte den Eindruck, dass die Navigationsfunktionalität noch überprüft wird.

Immer noch keine UWP-Unterstützung. Die größte Enttäuschung, die ich je von Xamarin hatte.

@weitzhandler Bitte mailen Sie mir an paul. [email protected], wenn Sie dies und UWP im Allgemeinen besprechen möchten. Wir ignorieren die Plattform nicht aktiv, aber Android und iOS erhalten die erste Implementierung und die Untersuchungen zur Shell-Unterstützung für UWP laufen derzeit.

@mrlacey Nein , es ist noch lange nicht fertig! Es wird nur durch verwandte Probleme geschlossen. 😄

Für alle, die nach UWP-Unterstützung fragen, habe ich es ausprobiert :

Gibt es eine Möglichkeit, eine Navigationsleistenvorlage auf der Inhaltsseite zu implementieren?
Die Angabe von NavigationPage.TitleView gilt nicht mehr wie zuvor.
Repo als Referenz:
https://github.com/InquisitorJax/Xamarin-Forms-Shell

BEARBEITEN:
Murphy schlägt wieder zu - benutze einfach Shell.TitleView anstelle von NavigationPage.TitleView :)

Hallo,
In meinem neuen Projekt verwende ich Shell und CollectionView, und ich muss sagen, das sind großartig!
Eine Frage zu Shell

  • es gibt eine Möglichkeit, ein unteres Element hinzuzufügen behoben (Fox-Beispiel eine Schaltfläche zum Abmelden des Benutzers)

Ich sehe, dass es möglich ist, eine feste Kopfzeile hinzuzufügen (FlyoutHeader und FlyoutHeaderBehavior), aber ich kann keine Informationen zur unteren Fußzeile finden
Vielen Dank!

Hallo,
Ich habe noch eine Frage zu RegisterRoute.
Meine App ist ziemlich groß, mit einer beträchtlichen Anzahl von Seiten, etwa 30...
Ist es wirklich der richtige Weg, die RegisterRoute für jeden von ihnen hinzuzufügen?
Routing.RegisterRoute("blabla", typeof(BlaBlaPage)); ... ...
Oder ist es besser, den alten Weg zu verwenden?
var blaPage = new BlaBlaPage (); await Navigation.PushAsync (blaPage);

@matteopiccioni Ich würde empfehlen, es so zu machen

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

und verwenden
gotoasync("blabla")

Mir ist klar, dass es sich im Moment genauso anfühlt, aber wenn die Funktionen wachsen, wird es relevanter, all diese Dinge über das Shell-System zu betreiben

Ist es wirklich der richtige Weg, die RegisterRoute für jeden von ihnen hinzuzufügen?

Wenn dies zu einem Problempunkt wird, prüfen wir, ob wir einige Funktionen hinzufügen, die nur nach Seiten durch die Assemblierung scannen, oder vielleicht sogar einige Funktionen zur Kompilierzeit, die diese Routen generieren.

Das Hauptproblem dabei ist, dass jede Art von Reflexion Ihre App verlangsamen wird, so dass dies beim Start kostet

@PureWeen danke für die Antwort
Langsame Startzeit ist eines der nervigsten Probleme in xf (für Android)
Könnte ich beim Start nur die erste Ebene der Seiten (die Shellitems-Seiten) zum Routing hinzufügen und die anderen erst hinzufügen, nachdem die App gestartet wurde (eine Art Lazy Loading von RegisterRoute)?

@matteopiccioni

Also wenn du es einfach so auf einmal machst

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

Das ist gut. Alles, worüber ich gesprochen habe, ist, dass wir es gegen die Leistung abwägen müssen, wenn wir am Ende etwas bauen, das es den Benutzern nicht mehr macht. Im Moment macht Routing.RegisterRoute("blabla", typeof(BlaBlaPage)); keine Reflexion, also ist es in Ordnung, alles auf einmal zu tun.

Alles, was es tut, ist, eine Zeichenfolge und einen Typ zu einem Wörterbuch hinzuzufügen

@jassmith @jamesmontemagno @pierceboggan Wow sieht toll aus. Haben Sie die Google Contacts-Anwendung mit Pie SDK auf einem Google Pixel gesehen? Ich liebe die UI/UX, ohne Titelleiste und den Hamburger, der oben in der App integriert ist.

Kann dieser Vorschlag für Ihre Shell in Betracht gezogen werden, da es sich um ein Muster handelt, das Google mit Kontakten und Karten und möglicherweise anderen verwendet?

Vielen Dank für Ihre Zeit und Rücksicht,

Karl

Beachten Sie, dass alle folgenden Beispiele keine ShellContents mit Vorlagen verwenden, die an anderer Stelle in der Spezifikation erläutert werden. Wenn ShellContents nicht ordnungsgemäß mit einem ContentTemplate verwendet wird, werden alle Seiten beim Start geladen, was sich negativ auf die Startleistung auswirkt. Diese Beispiele dienen nur zu Lernzwecken.
Glücklicherweise ist die Verwendung von ShellContents mit ContentTemplates normalerweise prägnanter, als sie nicht zu verwenden.
[…]
Ein Hauptproblem bei der Verwendung der Shell ist die Leichtigkeit, mit der ein Benutzer beim Start seiner Anwendungsausführung alle Seiten laden kann. Diese große Frontloading-Zuweisung kann zu einer ziemlich schlechten Startleistung führen, wenn eine große Anzahl von Inhaltsseiten benötigt wird. Um dies zu beheben, sollte nach Möglichkeit Templating verwendet werden.

Für mich hört sich das so an, als sollte man Inhalte nie direkt verwenden, sondern Vorlagen verwenden. Das macht für mich Sinn, warum also den direkten Content-Ansatz unterstützen? (abgesehen von der Einfachheit, aber es lässt die Leute sich selbst in den Fuß schießen). Es fühlt sich an, als ob die Möglichkeit, direkte Inhalte zu verwenden, eher eine "großartige Funktion bei einer Demo - ansonsten schreckliche" Funktion ist.

Hi,
Ich bin neu hier. Ich bin mir nicht sicher, ob dies der richtige Ort ist, um Fragen zu stellen, andernfalls weisen Sie mich bitte an, wo ich fragen soll:
Ich habe versucht, etwas Ähnliches wie das oben angegebene Beispiel zu tun:

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

Aber ich habe folgende Fehler bekommen:

Fehler XLS0413 Die Eigenschaft 'ItemsSource' wurde im Typ 'ShellItem' nicht gefunden.
Fehler XLS0415 Die anfügbare Eigenschaft 'ItemTemplate' wurde im Typ 'ShellItem' nicht gefunden.

@PureWeen Ich hatte gehofft, diese Idee zu verwenden :) .
Wollen Sie damit sagen, dass diese Idee noch nicht umgesetzt wurde?
Wenn es noch nicht implementiert ist, könnte ich daran interessiert sein, daran zu arbeiten.

@Elashi ist es nicht, aber ich konnte sehen, dass dies eine wirklich leistungsstarke Funktion für MVVM-Szenarien ist

Wenn Sie daran arbeiten möchten, können Sie ein Problem mit den Grundlagen Ihrer Gedanken erstellen?

Also aus Versuch und Irrtum ... Obwohl es Kommentare zu Gesten in Shell 3.2 und in TheLittlePlayground gibt, kann ich Gesten nicht mein Leben lang mit dem visuellen Paket auf ANDROID funktionieren lassen.

Übersehe ich etwas in den Notizen, dass Shell + Gesten nur mit dem iPhone funktionieren?

@davidortinau Ich weiß, dass dies nur einige Spezifikationen sind und es seit einiger Zeit geschlossen ist, aber ich hatte gehofft, dass Sie mich in die richtige Richtung weisen können, da die Spezifikationen darauf hinweisen, dass die folgende Aufgabe entweder abgeschlossen ist oder auf der Liste steht für Entwicklung:

  • API für "Untermenü"-Elemente für ShellContents ala GPS hinzufügen -> Musik -> Musik-App öffnen

Da ich GroupHeaders derzeit nicht zum Laufen bringen kann, möchte ich mein FlyoutMenu überarbeiten, um es in 6 Hauptgruppen zu sortieren und dann ein Untermenü voller FlyoutItems erscheinen zu lassen, das mich zu der von mir vorgegebenen Route führt.

Mein Anwendungsfall ist, dass ich mehr als 50 Optionen zum Anzeigen habe, und das Versetzen in einen Bildlaufzustand ist nicht UI-freundlich, aber jede anzuzeigende Option ist etwas, das ich meinen Benutzern ermöglichen muss, effizient zu gelangen, ohne endlos scrollen zu müssen. Das Sortieren in Gruppen basierend auf dem übergreifenden Thema jeder Option ist aus UI/UX-Sicht am sinnvollsten.

Können Sie etwas Licht ins Dunkel bringen, wo das in Bezug auf Entwicklung / Produktion steht? - oder weisen Sie mich auf eine Codebasis hin, die es implementiert, damit ich lernen kann? (Ich bin erst seit 1 Monat bei Xamarin, daher sind mir einige der verfügbaren Ressourcen noch neu).

@TheBaileyBrew

Ich habe gerade dieses Repo mit etwas gegoogelt, das höchstwahrscheinlich für Ihr Szenario funktionieren könnte. Es wird keine Shell sein, aber Sie könnten es wahrscheinlich in einem MasterDetailPage-Setup verwenden.

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

Außerdem haben sie gerade einen Großteil ihres Kursmaterials auf MSFT Learn verschoben und aktualisiert (das ich selbst durchlaufe, um die Lücken zu schließen). Das finden Sie hier: https://docs.microsoft.com/en-us/learn/browse/?products=xamarin

Ich würde versuchen, die oben genannten Punkte durchzugehen. Viel Glück und willkommen an Bord!

Hallo Leute, ich möchte Dateien oder Fotos aus der Galerie oder dem externen Speicher in auswählen
xamarin-Formulare, die die Datei auswählen sollen? Die Datei hat nur die Erweiterung .PDF. Zu
Wählen Sie beide Dateien aus Ich benutze eine Schaltfläche, also bitte helft mir!!!

Am Do, 23. Mai 2019, 19:41 Uhr schrieb Anthony Cool

@TheBaileyBrew https://github.com/TheBaileyBrew

Ich habe gerade dieses Repo mit etwas gegoogelt, das für Ihr Szenario funktionieren könnte
höchstwahrscheinlich. Es wird keine Shell sein, aber Sie können es in einer MasterDetailPage verwenden
wahrscheinlich einrichten.

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


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/xamarin/Xamarin.Forms/issues/2415?email_source=notifications&email_token=AK7KSYK4N3XIVP3IHOBE2P3PW3CKJA5CNFSM4EZ4GB52YY3PNVWWK3TUL52HS4DFVREXG43VMVBWKT#DN47
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AK7KSYI5XKMXD7FC7HZH45LPW3CKJANCNFSM4EZ4GB5Q
.

Hey Leute, ich möchte Registerkarten auf der Grundlage der Bedingung hinzufügen.

@BeleShew Ihre Frage ist wahrscheinlich besser geeignet für Stackoverflow oder bei forums.xamarin.com

@PWaliaDev Sie würden dies über die verschiedenen Items-Sammlungen tun, die Teil der Shell sind

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

Obwohl ich davon ausgehe, dass wir dieses Problem behoben haben
https://github.com/xamarin/Xamarin.Forms/issues/5428

das würde zu deinem Szenario passen?

@PureWeen - Ich habe die Anzeigeoptionen für Ihren Link festgelegt, aber womit ich zu kämpfen habe, ist näher an dem,

Fixing #5428 würde zu dem passen, was ich erreichen möchte.

Meine App hat Benutzer mit einer Vielzahl von Rollen/Zugriffen und ich muss Menüoptionen programmgesteuert nur den autorisierten Benutzern anzeigen (ich möchte nicht, dass Benutzer sehen, was sie _ nicht _ tun

Obwohl ich damit herumgespielt habe und versucht habe herauszufinden, ob es möglich ist, meine Menüoptionen zu überprüfen und sie hinzuzufügen, anstatt sie auszublenden, wie es dieser Code tut (aber ich müsste gegen jede mögliche Route und Menüoption iterieren, die auffressen würde) Ladezeit:

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 ist in der Theorie großartig, aber in der Praxis nicht ohne diese Funktionen.

  1. Shell-Elemente dynamisch basierend auf der Benutzerrolle hinzufügen/entfernen
  2. Login/Logout-Szenario oder zwei separate Navigationsrouten je nach Bedingungen.
  3. Optional Unterstützung für andere MVVM-Frameworks wie Prism

Shell kann in geschäftsorientierten Apps erst verwendet werden, wenn Feature 1 und 2 bereitgestellt werden.

@Im-PJ Warum glauben Sie, dass 1 und 2 nicht möglich sind? (ziemlich sicher sind sie es)

3 ist in Bearbeitung und wird hier verfolgt.

Weiß jemand, ob es möglich ist, ein Tap-Ereignis von einer App Shell-Registerkarte zu erhalten?
verwandte Forumsfrage: https://forums.xamarin.com/discussion/159748/app-shell-pop-to-root-on-tab-tap

Stimme @Im-PJ voll und ganz zu und verstehe nicht, warum diese Funktionen nicht speziell bereitgestellt werden. Dies ist ein Hauptgrund für ein Tool wie Shell. Jeder kann ein Slide-Out-Menü erstellen!

@dotMorten vielleicht können Sie 1 oder 2 durch umfangreiches C# und Hacking tun, aber es gibt KEINE Beispiele oder Erwähnungen des Bindens/Deaktivierens/Ausblendens/Hinzufügens von Shell-Elementen zur Laufzeit, die ich finden kann. Es scheint, dass dynamische Fähigkeiten ein Hauptziel dieses Tools gewesen wären. Das Erstellen einer XML-Darstellung zusammen mit einigen Pfadfunktionen ist das absolute Minimum, genug, um es den Marketingleuten zur Verfügung zu stellen, aber nicht ausreichend, um es tatsächlich in einer echten, voll ausgestatteten mobilen App zu verwenden.

@Im-PJ

Können Sie ein wenig erläutern, wie sich diese unterscheiden?

Shell-Elemente dynamisch basierend auf der Benutzerrolle hinzufügen/entfernen
Login/Logout-Szenario

Derzeit können Sie ein Login/Logout-Szenario durchführen, indem Sie eine TabBar verwenden oder die Flyout-Navigation ausblenden, wenn Sie sich auf einer Login-Seite befinden

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

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

Wenn Sie sich auf der Anmeldeseite befinden, können Sie nur durch Code navigieren.

Hier wird daran gearbeitet, eine bindbare IsVisible-Eigenschaft verfügbar zu machen
https://github.com/xamarin/Xamarin.Forms/tree/shell_isvisible

Es muss nur ein wenig verfeinert werden, bevor ein PR erstellt wird

zwei separate Navigationsrouten je nach Bedingungen.

Können Sie Beispiele dafür nennen, was Sie versuchen und derzeit nicht tun können?

hoi1
Ich verwende die Xamarin.Form-Shell

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

Bitte hilf mir. Wie zeige ich die Tabbar auf der Info-Seite an?

Ich brauche zwei Shell-Seiten gleichzeitig.
Eine für ein Flayout-Menü mit Seite als Startseite, Einstellungen, Abmeldung usw.
Eine für Tabbedpages, die von zu Hause gepusht werden sollen
Für jetzt muss ich den 'alten Weg' verwenden

Ich brauche zwei Shell-Seiten gleichzeitig.
Eine für ein Flayout-Menü mit Seite als Startseite, Einstellungen, Abmeldung usw.
Eine für Tabbedpages, die von zu Hause gepusht werden sollen
Für jetzt muss ich den 'alten Weg' verwenden

Bei Verwendung von Tabbedpage kann Flyout nicht angezeigt werden. Ich möchte Flyout und Tabbar diesmal zeigen.

Ich habe alle Seiten in diedamit die Seiten die Tabbar anzeigen, aber ich möchte nur 4 Elemente in der Tabbar haben (möchte nicht mehr Tab anzeigen). Wie zu tun?

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

Ich brauche zwei Shell-Seiten gleichzeitig.
Eine für ein Flayout-Menü mit Seite als Startseite, Einstellungen, Abmeldung usw.
Eine für Tabbedpages, die von zu Hause gepusht werden sollen
Für jetzt muss ich den 'alten Weg' verwenden

Bei Verwendung von Tabbedpage kann Flyout nicht angezeigt werden. Ich möchte Flyout und Tabbar diesmal zeigen.

Ich füge alle Seiten in die ein, damit die Seiten die Tabbar anzeigen, aber ich möchte nur 4 Elemente in der Tabbar haben (möchte nicht mehr Tab anzeigen). Wie zu tun?

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

Leider kann ich Shell nicht verwenden
Ich habe immer noch MasterDetailPage und TabbedPage in derselben App (in iOS habe ich Top-Tabbed-Seiten mit dem Naxam.TopTabbedPage.Forms-Plugin)
Das war mein altes Ticket

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen