<p>Спецификация Xamarin.Forms.Shell</p>

Созданный на 10 апр. 2018  ·  199Комментарии  ·  Источник: xamarin/Xamarin.Forms

Спецификация оболочки Xamarin.Forms

Упростите и упростите для новых разработчиков получение полноценного опыта работы с приложением, который правильно структурирован, использует правильные элементы, с минимальными усилиями и с четким путем к хорошему по умолчанию.

Shell - это упрямый API в некоторых точках, он не всегда устанавливает каждое значение по умолчанию для некоторых .Default, которые могут меняться в зависимости от работающей платформы. Вместо этого он может установить значение, которое затем будет соблюдаться на всех платформах, независимо от того, какая платформа установлена ​​по умолчанию.

Примечание. Спецификация чертежа перемещена по адресу: # 2452.

Визуальное лечение

Нужны скриншоты ...

Иерархия оболочки

Поначалу понимание иерархии Shell может показаться сложным. Он представляет собой сложную иерархию и предоставляет мощные механизмы для минимизации количества шаблонного xaml, необходимого для создания богатых иерархий.

Таким образом, при первом изучении оболочки проще всего изучить сначала без ярлыков, а затем ввести ярлыки, чтобы увидеть, как легко минимизировать объем записываемого XAML.

Обратите внимание, что во всех следующих примерах не используются шаблонные ShellContent, которые обсуждаются в другом месте спецификации. Неправильное использование ShellContents с ContentTemplate приведет к загрузке всех страниц при запуске, что отрицательно скажется на производительности запуска. Эти образцы предназначены только для обучающих целей.

К счастью, использование ShellContents с ContentTemplates обычно более лаконично, чем их неиспользование.

Нет ярлыков

Многие из этих образцов будут выглядеть излишне сложными, и на самом деле так оно и есть. В следующем разделе они будут упрощены.

Простое одностраничное приложение

<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

Верхнюю панель можно полностью скрыть, установив Shell.NavBarVisible="false" на MainPage. Всплывающее окно также выглядело бы довольно разреженным в этом режиме и поэтому отключено в этом примере.

Двухстраничное приложение с нижними вкладками

<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

При добавлении раздела ShellSection к ShellItem появляется еще одна нижняя вкладка. Настройки соответствующего заголовка и значка позволяют управлять заголовком и значком элемента вкладки.

Двухстраничное приложение с верхней и нижней вкладками

<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

При добавлении второго ShellContent к ShellSection добавляется верхняя панель вкладок, и страницы можно перелистывать, когда выбрана нижняя вкладка.

Двухстраничное приложение с всплывающей навигацией

<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

Всплывающее меню повторно включено в этом примере. Здесь пользователь может переключаться между двумя страницами, используя всплывающее окно в качестве посредника. Также был добавлен заголовок, чтобы он выглядел красиво.

Использование сокращенного синтаксиса

Теперь, когда все уровни иерархии показаны и кратко объяснены, можно оставить большую часть ненужной упаковки при определении иерархии. Shell содержит только ShellItem s, которые всегда содержат только ShellSection s, которые, в свою очередь, содержат только ShellContent s. Однако существуют неявные операторы преобразования, позволяющие автоматически выполнять упаковку.

Простое одностраничное приложение

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

При неявном переносе страница автоматически переносится до ShellItem . Нет необходимости выписывать все промежуточные слои. Title и Icon из Page будут связаны с любыми неявно сгенерированными родителями.

Двухстраничное приложение с нижними вкладками

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

Теперь страницы неявно заключены в ShellContent и свои собственные ShellSections. В результате, как и раньше, создаются две разные вкладки.

Двухстраничное приложение с верхней и нижней вкладками

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

Двухстраничное приложение с всплывающей навигацией

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

Здесь неявное обертывание идет вплоть до элемента оболочки, поэтому нам не нужно делать какое-либо обертывание самостоятельно.

Модель навигации

Нажать навигацию

Вся навигация основана на свойстве View .Navigation. Нажимы переходят в текущий отображаемый ShellSection. Это означает, что в событии push верхние вкладки исчезнут, а нижние останутся.

URI-навигация

В оболочке можно перемещаться с помощью стандартного свойства Navigation, как обсуждалось выше, однако оболочка представляет гораздо более удобный механизм навигации.

URI навигации имеют следующий формат:

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

Все элементы в иерархии оболочки имеют связанный с ними маршрут. Если маршрут не задан разработчиком, он создается во время выполнения. Маршруты, сгенерированные во время выполнения, не гарантируют стабильности при разных запусках приложения и, следовательно, бесполезны для глубинных ссылок.

Работа с кнопкой "Назад"

Поскольку Shell окажется в завидном положении, так как ей не придется использовать собственные элементы управления, все формы переопределения кнопки «Назад» могут и должны поддерживаться.

Правильное обращение с кнопкой возврата должно поддерживать следующие функции:

  • Перехват взаимодействий и их остановка
  • Замена кнопки возврата на что-то другое
  • Полное скрытие кнопки возврата при желании
  • Работа для программных и аппаратных кнопок

API должен быть детализированным до уровня страницы для простоты использования, но также должен иметь возможность обрабатываться дальше по стеку на более общем уровне.

Примеры кода и API

Образцы

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

Одностраничное приложение с использованием оболочки

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

Приложение для одной группы вкладок (без всплывающего меню)

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

Несколько страниц во всплывающем меню без вкладок

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

Одностраничное приложение с возможностью поиска

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

`` csharp
открытый класс MyPage: ContentPage
{
открытый класс MyPageSearchHandler: SearchHandler
{
общедоступный MyPageHandler ()
{
SearchBoxVisibility = SearchBoxVisibility.Collapsed;
IsSearchEnabled = true;
Placeholder = "Найди меня!";
}

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
}

}

общедоступная MyPage ()
{
Shell.SetSearchHandler (это, новый 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);
}

Описание

Прикрепленные свойства:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| SearchHandlerProperty | Прикрепленное свойство для определения возможности поиска на уровне страницы. Может быть прикреплен в нескольких точках иерархии. Использует некоторые из функций, определенных здесь https://material.io/guidelines/patterns/search.html#search -in-app-search |
| BackButtonBehavior | Позволяет полностью изменить поведение кнопки «Назад». Применяется к экранным и физическим кнопкам возврата. |
| FlyoutBehavior | Определяет, как должен выглядеть всплывающий элемент. Его можно присоединить к ShellItem s, ShellContent s или Page s, чтобы переопределить поведение по умолчанию. |
| NavBarVisibleProperty | Свойство, заданное для Page определяет, должна ли панель NavBar быть видимой при ее представлении |
| SetPaddingInsetsProperty | Установка этого свойства на Page приведет к тому, что его Padding будет установлено таким образом, что его содержимое не будет перемещаться под каким-либо хромом оболочки. |
| TabBarVisibleProperty | Свойство устанавливается для Page чтобы определить, должна ли TabBar быть видимой при ее представлении |
| TitleViewProperty | Свойство установлено на Page для определения TitleView |
| ShellBackgroundColorProperty | Описывает цвет фона, который следует использовать для хромированных элементов оболочки. Этот цвет не будет заливать Контент оболочки. |
| ShellDisabledColorProperty | Цвет для затенения отключенного текста / значков |
| ShellForegroundColorProperty | Цвет для затенения обычного текста / значков в оболочке |
| ShellTabBarBackgroundColorProperty | Переопределение ShellBackgroudnColor для TabBar. Если не установлено, будет использоваться ShellBackgroundColor |
| ShellTabBarDisabledColorProperty | Переопределение ShellDisabledColor для TabBar. Если не установлено, будет использоваться ShellDisabledColorProperty |
| ShellTabBarForegroundColorProperty | Переопределение ShellForegroundColorProperty для TabBar. Если не установлено, будет использоваться ShellForegroundColorProperty |
| ShellTabBarTitleColorProperty | Переопределение ShellTitleColorProperty для TabBar. Если не установлено, будет использоваться ShellTitleColorProperty |
| ShellTabBarUnselectedColorProperty | Переопределение ShellUnselectedColorProperty для TabBar. Если не установлено, будет использоваться ShellUnselectedColorProperty |
| ShellTitleColorProperty | Цвет, используемый для заголовка текущей страницы |
| ShellUnselectedColorProperty | Цвет невыделенного текста / значков в оболочке chrome |

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| CurrentItem | Текущий выбранный ShellItem |
| CurrentState | Текущее состояние навигации оболочки. Передача этого состояния обратно в GoToAsync приведет к тому, что оболочка вернется для перехода к предыдущему состоянию. |
| FlyoutBackgroundColorProperty | Цвет фона всплывающего меню |
| FlyoutBehavior | Устанавливает значение по умолчанию FlyoutBehavior для Shell . |
| FlyoutHeader | Объект, используемый в качестве заголовка всплывающего окна. Если FlyoutHeaderTemplate не равно нулю, это передается как BindingContext завышенному объекту. Если FlyoutHeaderTemplate имеет значение null, а FlyoutHeader имеет тип View он будет использоваться напрямую. В противном случае это будет показано путем вызова ToString () и отображения результата. |
| FlyoutHeaderBehavior | Устанавливает поведение FlyoutHeader когда всплывающее окно необходимо прокрутить для отображения содержимого. |
| FlyoutHeaderTemplate | Шаблон, используемый для создания заголовка для всплывающего окна. |
| FlyoutIsPresent | Получает или задает, является ли всплывающее окно видимым в данный момент |
| GroupHeaderTemplate | DataTemplate используется для отображения заголовка группы, если ShellItem запрашивает отображение в виде группы вкладок во всплывающем меню. Если null, заголовок не отображается. |
| Предметы | Основное содержимое оболочки. Элементы определяют список элементов, которые будут отображаться во всплывающем меню, а также контент, который будет отображаться при выборе элемента боковой панели. |
| ItemTemplate | DataTemplate используется для отображения элементов из коллекции Items во всплывающем меню. Позволяет разработчику управлять визуальными элементами во всплывающем меню. |
| MenuItems | Коллекция MenuItem s, которая будет отображаться во всплывающем меню в отдельном разделе. |
| MenuItemTemplate | DataTemplate для использования при отображении MenuItem во всплывающем меню. |
| Маршрут | Часть маршрута для адресации этого элемента при выполнении глубокой ссылки. |
| RouteHost | Строка, которую нужно поместить в хост-часть URI, сгенерированного при создании глубоких ссылок |
| RouteScheme | Строка, которую нужно поместить в часть схемы URI, сгенерированного при создании глубоких ссылок |

Публичные методы:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| GoToAsync | Перейдите к ShellNavigationState . Возвращает задачу, которая завершится после завершения анимации. |

Общественные мероприятия:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Навигация | Shell собирается выполнить навигацию либо из-за взаимодействия с пользователем, либо из-за вызова API разработчиком. Разработчик может отменить навигацию здесь, если это возможно. |
| С навигацией | Shell завершил событие навигации. |

ShellItemCollection

Коллекция за ShellItem s

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

MenuItemCollection

Коллекция за MenuItem s

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

ShellSectionCollection

Коллекция за ShellSection s

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

ShellContentCollection

Коллекция за ShellContent s

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

ShellNavigatingEventArgs

EventArgs используется для описания события навигации, которое вот-вот произойдет. ShellNavigationEventArgs также может использоваться для отмены события навигации, если разработчик пожелает.

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

  public ShellNavigationState Target { get; }

  public ShellNavigationSource Source { get; }

  public bool CanCancel { get; }

  public bool Cancel ();
}

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Текущий | Текущее состояние NavigationState Shell . Вызов GoToAsync с этим ShellNavigationState эффективно отменяет это событие навигации. |
| Target | Состояние, в котором будет находиться Shell после завершения этого события навигации. |
| Источник | Тип навигации, вызвавшей это событие. Может быть установлено несколько флагов. |
| CanCancel | Независимо от того, отменяется ли событие навигации. Не все мероприятия можно отменить. |

Публичные методы:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Отмена | Отменяет текущее событие навигации. Возвращает истину, если отмена прошла успешно. |

ShellNavigatedEventArgs

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

  public ShellNavigationState Current { get; }

  public ShellNavigationSource Source { get; }
}

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Предыдущая | Предыдущее состояние NavigationState Shell . |
| Текущий | Новое состояние, в котором находится Shell когда это событие навигации завершено. |
| Источник | Тип навигации, которая инициировала это событие. Может быть установлено несколько флагов. |

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

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Расположение | Uri, который описывает состояние навигации Shell |

Конструкторы:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| (недействительно) | Создает новый ShellNavigationState с нулевым Location |
| (Строка) | Создает новый ShellNavigationState с Location, установленным на предоставленный string |
| (Ури) | Создает новый ShellNavigationState с Location, установленным на предоставленный 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; }
}

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| FlyoutIcon | Значок по умолчанию для использования при отображении во всплывающем меню. Если не задан, по умолчанию будет установлен значок. |
| Иконка | Значок, отображаемый в частях хрома, не являющихся всплывающим элементом. |
| IsChecked | Если BaseShellItem в настоящее время отмечен во всплывающем меню (и, следовательно, должен быть выделен) |
| IsEnabled | Если BaseShellItem можно выбрать в хроме |
| Маршрут | Аналогично настройке Routing.Route |
| Название | Заголовок для отображения в пользовательском интерфейсе |

ShellGroupItem

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

  public FlyoutDisplayOptions FlyoutDisplayOptions { get; set; }
}

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| FlyoutDisplayOptions | Управляет тем, как этот элемент и его дочерние элементы отображаются во всплывающем меню |

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

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| CurrentItem | Выбранные ShellSection . |
| Предметы | ShellSectionCollection который является основным содержимым ShellItem. Эта коллекция определяет все вкладки в ShellItem. |

ShellSection

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

  public ShellSection();

  public ShellContent CurrentItem { get; set; }

  public ShellContentCollection Items { get; }

  public IReadOnlyList<Page> Stack { get; }

  public static implicit operator ShellSection(ShellContent shellContent);

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

  protected virtual IReadOnlyList<Page> GetNavigationStack();

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

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

  protected virtual async Task OnPopToRootAsync(bool animated);

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

  protected virtual void OnRemovePage(Page page);
}

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| CurrentItem | Выбранный ShellContent в ShellSection. |
| Предметы | ShellContentCollection который является корневым содержимым ShellSection. |
| Стек | Текущий перемещаемый стек навигации в ShellSection. |

Методы:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| GoToAsync | Используется с помощью внешних ссылок для перехода к известному месту. В большинстве случаев нет необходимости вызывать напрямую. |
| GetNavigationStack | Возвращает текущий стек навигации |
| OnInsertPageBefore | Вызывается при вызове метода INavigation interfaces InsertPageBefore |
| OnPopAsync | Вызывается при вызове метода INavigation interfaces PopAsync |
| OnPopToRootAsync | Вызывается при вызове метода INavigation interfaces PopToRootAsync |
| OnPushAsync | Вызывается при вызове метода INavigation interfaces PushAsync |
| OnRemovePage | Вызывается при вызове метода INavigation interfaces RemovePage |

ShellContent

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

  public ShellContent();

  public object Content { get; set; }

  public DataTemplate ContentTemplate { get; set; }

  public MenuItemCollection MenuItems { get; }

  public static implicit operator ShellContent(TemplatedPage page);
}

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Содержание | Содержимое ShellContent. Обычно ContentPage или BindingContext из Page раздувают ContentTemplate |
| ContentTemplate | Используется для динамического расширения содержимого ShellContent . Свойство Content будет установлено как BindingContext после инфляции. |
| MenuItems | Элементы, отображаемые во всплывающем меню, когда этот ShellContent является представленной страницей |

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

Характеристики:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| ClearIconHelpText | Доступный текст справки для прозрачного значка |
| ClearIconNameProperty | Название прозрачного значка для использования с программами чтения с экрана |
| ClearIcon | Значок отображается, чтобы очистить содержимое поля поиска. |
| ClearPlaceholderCommandParameter | Параметр для ClearPlaceholderCommand |
| ClearPlacehodlerCommand | Команда, выполняемая при нажатии значка ClearPlaceholder |
| ClearPlaceholderEnabled | Включенное состояние ClearPlaceholderIcon. По умолчанию верно. |
| ClearPlaceholderHelpText | Доступный текст справки для четкого значка заполнителя |
| ClearPlaceholderIcon | Значок отображается в ячейке ClearIcon когда поле поиска пусто. |
| ClearPlaceholderName | Имя прозрачного значка-заполнителя для использования с программами чтения с экрана |
| CommandParameter | Параметр для Command |
| Команда | ICommand для выполнения при подтверждении запроса
| DisplayMemberPath | Имя или путь к свойству, которое отображается для каждого элемента данных в ItemsSource . |
| IsSearchEnabled | Управляет включенным состоянием поля поиска. |
| ItemsSource | Коллекция элементов для отображения в области предложений. |
| ItemTemplate | Шаблон для элементов, отображаемых в области предложений. |
| Заполнитель | Строка, отображаемая, когда поле поиска пусто. |
| QueryIconHelpTextProperty | Доступный текст справки для значка запроса |
| QueryIconNameProperty | Имя значка запроса для использования с программами чтения с экрана |
| QueryIcon | Значок, используемый для указания пользователю, что поиск доступен |
| Запрос | Текущая строка в поле поиска. |
| SearchBoxVisibility | Определяет видимость окна поиска в Chrome Shell s. |
| ShowsResults | Определяет, следует ли ожидать результатов поиска при вводе текста |

Защищенные методы:

| API | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| OnClearPlaceholderClicked | Вызывается при каждом нажатии значка ClearPlaceholder. |
| OnItemSelected | Вызывается всякий раз, когда пользователь нажимает на результат поиска |
| OnQueryConfirmed | Вызывается всякий раз, когда пользователь нажимает клавишу ввода или подтверждает свой ввод в поле поиска. |
| OnQueryChanged | Вызывается при изменении Query . |

SearchBoxVisiblity

public enum SearchBoxVisiblity
{
  Hidden,
  Collapsable,
  Expanded
}

| Значение | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Скрытый | Поле поиска не отображается и не доступно. |
| Складной | Поле поиска скрыто до тех пор, пока пользователь не откроет его. |
| Расширенный | Поле поиска отображается как полностью развернутая запись. |

BackButtonBehavior

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 | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| IconOverride | Изменяет значок, используемый для кнопки возврата. |
| TextOverride | Изменяет текст, используемый для обозначения обратной навигации, если используется текст. |
| Команда | Предоставляет команду замены, вызываемую при нажатии кнопки возврата. |
| CommandParameter | Параметр команды, используемый с Command |

FlyoutDisplayOptions

Определяет, как ShellGroupItem должно отображаться в FlyoutMenu.

  public enum FlyoutDisplayOptions
  {
    AsSingleItem,
    AsMultipleItems,
  }

| Значение | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| AsSingleItem | ShellGroupItem будет отображаться как отдельная запись во всплывающем меню. |
| AsMultipleItems | ShellGroupItem будет отображаться как группа элементов, по одному для каждого дочернего элемента в раскрывающемся списке. |

FlyoutHeaderBehavior

Управляет поведением FlyoutHeader при прокрутке.

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

| Значение | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| По умолчанию | Поведение платформы по умолчанию. |
| Исправлено | Заголовок всегда остается видимым и неизменным |
| Прокрутка | Заголовок исчезает из поля зрения, когда пользователь прокручивает меню |
| CollapseOnScroll | Заголовок сворачивается в заголовок только при прокрутке пользователем |

FlyoutBehavior

public enum FlyoutBehavior
{
  Disabled,
  Flyout,
  Locked
}

| Значение | Описание |
| ----------- | -------------------------------------------------- -------------------------------------------- |
| Отключено | Пользователь не может получить доступ к всплывающему окну. |
| Всплывающее окно | Всплывающее окно работает как обычное всплывающее окно, которое пользователь может открывать / закрывать. |
| Заблокировано | Всплывающее окно заблокировано и не может быть закрыто пользователем, оно не перекрывает содержимое. |

DataTemplateExtension

Это расширение быстро преобразует тип в ControlTemplate. Это полезно для случаев, когда в противном случае шаблон был бы указан как

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

Затем это можно сжать до

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

Шансы и концы

Что происходит, когда вы выбираете вкладку во всплывающем меню, на которую была перемещена?

Это эквивалент фокусировки вкладки и вызова на ней PopToRoot.

Что происходит, когда я переключаю ShellItems и есть элементы в backstack ShellContent старого ShellItem

Если старый ShellItem является шаблоном, задний стек теряется. Если ShellItem не является шаблоном, BackStack остается неизменным, и при переключении обратно на старый ShellItem backstack будет правильно отражен. Обратное переключение может очистить backstack, однако, как указано в приведенном выше ответе.

Эффективная загрузка страниц

Основная проблема с использованием Shell - это легкость, с которой пользователь может в конечном итоге загрузить все страницы в начале запуска своего приложения. Это большое выделение с предварительной загрузкой может привести к довольно низкой производительности при запуске, если требуется большое количество страниц с содержимым. Для исправления этого шаблона следует по возможности использовать.

Шаблонная оболочка

Шаблоны элементов вкладок оболочки - это наиболее детализированная форма шаблонов из доступных, но, к счастью, также и самая простая в реализации. Возьмите следующую оболочку.

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

Когда эта оболочка загружается, все 9 страниц будут раздуты одновременно. Это потому, что не используются шаблоны. Чтобы использовать базовые шаблоны, мы можем преобразовать это в:

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

Страницы теперь загружаются только по мере необходимости и могут быть выгружены по мере необходимости. При необходимости сами ShellItem также могут быть шаблонизированы с помощью коллекции и DataTemplateSelector, что предотвращает загрузку даже ShellContents, однако в этом нет необходимости, и создание шаблонов ShellItem более полезно для Shell, которые имеют ShellItems с большим количеством других похожих вкладок. . Создание шаблонов ShellContent должно быть ключевой областью для создания шаблонов для проблем производительности.

Реконструкция пользовательского интерфейса Google Play Store

Обратите внимание, что это не демонстрация лучшего способа кодирования приложения, а наиболее краткий формат для объединения пользовательского интерфейса для GPS. Он также не пытается виртуализировать соответствующие страницы с помощью ViewModels и DataTemplateSelector's. Это означает, что это будет довольно плохо, поскольку все страницы будут загружаться при запуске приложения. Читатель предупрежден.

Предполагается, что все содержимое страницы работает правильно, это только для того, чтобы получить общее представление о Chrome.

Shell.xaml

Правильная реализация этого будет использовать ShellItems для каждой страницы и устанавливать ItemsSource и ItemTemplate. Это позволит загружать каждую страницу только тогда, когда она нужна, и выгружать, когда она больше не нужна.

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

Страницы магазина

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

И добавить панель поиска.

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

И так далее, и так далее, правильно настраивая цвета и контент.

Для таких страниц, как страница настроек, где раскрывающееся меню не должно быть доступно, пока не будет нажата кнопка "Назад":

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

ДЕЛАТЬ

  • [x] Добавить API для окна поиска
  • [x] Добавить API для обработки ContentSafeArea
  • [x] Добавить API для плавающего меню
  • [x] Добавить API для пунктов меню окна
  • [x] Добавить API для закусочной
  • [x] Добавить API для прерывания навигации
  • [x] Добавить API для нижнего листа
  • [x] Добавить API в позицию FAB
  • [x] Добавьте истории, чтобы сделать навигационные идеи более понятными (частично выполнено)
  • [x] Добавить API стиля LeftBarButton
  • [x] Добавить механизм для возврата стека из ShellContent
  • [x] Добавить API для изменения цвета ленты в зависимости от выбранной вкладки
  • [x] Добавить дополнительную поддержку предложений для SearchHandler
  • [x] Добавить поддержку настройки всегда расширяемой панели поиска и панели поиска в виде значка.
  • [x] Добавить API для получения «текущей» страницы из класса MaterialShell. Требуется для некоторых сценариев навигации.
  • [x] Добавить API для сохранения "состояний" в задний стек
  • [x] Добавить API, чтобы заблокировать всплывающее окно
  • [x] Добавить API для элементов "подменю" для ShellContent ala GPS -> Музыка -> Приложение Open Music
  • [x] Добавить API для команды и значка CancelPlaceholder (обычно используется для значка микрофона для голосового поиска)
  • [x] API перехода
  • [x] Решите, что делать с INavigation
  • [] Разверните Bottom Sheet API, чтобы соответствовать возможностям Google Maps
  • [x] API для обработки всплывающей презентации
  • [] API для отключения жеста всплывающего окна при необходимости
  • [] API больших заголовков
  • [] Transitions API

Проблемы

ISearchHandler [ИСПРАВЛЕНО]

Этот интерфейс многое делает, и, что еще хуже, его, вероятно, придется расширять с течением времени. Поэтому логично предположить, что вместо этого он должен быть абстрактным базовым классом, который может реализовать пользователь. Это неудачное решение означает еще одно размещение объекта. Однако он сохраняет гибкость в будущем. Вполне вероятно, что это изменение произойдет.

Плавающее меню

API вложений немного тяжелый и, возможно, слишком запутанный для пользователей. Хуже того, это может не очень хорошо отображаться на всех платформах, чтобы убедиться, что вложение работает с анимацией. Для проверки этого API требуется дополнительная работа.

shell enhancement ➕

Самый полезный комментарий

Ребята, вчера мы с Джейсоном обсуждали, как улучшить эту спецификацию, и мы будем делать большое обновление, мы разбиваем это на разные проблемы.

Все 199 Комментарий

Давайте начнем разговор, потому что нам действительно нужно услышать ваше мнение, наше сообщество разработчиков!

Во-первых , спасибо постарался запечатлеть это и подготовил предложение для открытого обсуждения здесь.

Я собираюсь поделиться некоторыми своими мыслями, задать несколько глупых вопросов и задать несколько, надеюсь, не слишком наводящих вопросов. Как программный менеджер для Xamarin.Forms мне часто приходится задавать вопросы таким образом, что это звучит так, будто я не имею ни малейшего понятия (иногда нет), но на самом деле мне просто нужно слышать что-то от ВАС без вкладывать слова в рот.

В этом предложении есть вещи, которые мне нравятся, потому что я вижу, как они могут решить некоторые проблемы, о которых я говорил со многими, многими из вас, и мы работаем над их решением.

У меня тоже есть оговорки.

Я начну с нескольких общих мыслей о концепции Shell и опыте разработчиков.

Опыт приложения

чтобы получить полноценное приложение, которое правильно структурировано, использует правильные элементы, с очень небольшими усилиями и четким путем к хорошему по умолчанию.

Если я использую этот подход для описания своего приложения на верхнем уровне, я получаю:

  • тематическое приложение, которое будет выглядеть одинаково на всех платформах
  • материальный дизайн (в данном случае) выкройки включены по умолчанию
  • новейшие шаблоны навигации, включенные с конфигурацией
  • Мне не нужно трудиться, чтобы настроить Entry или Button, чтобы они выглядели одинаково на iOS, Android и UWP?

Это точно? Другие преимущества, которые я должен выделить?

Вместо App у меня MaterialShell . Мне нужно изучить / принять новую парадигму приложения верхнего уровня, чтобы извлечь из этого пользу?

Как только я вхожу в свое приложение, я снова нахожусь на земле ContentPage , верно? Но все мои Button s и Entry s материалистичны и красивы. Могу ли я по-прежнему OnPlatform и тому подобное изменить внешний вид (или поведение), чтобы отличаться на другой платформе?

Как выглядит мой путь миграции из существующего приложения в эту «оболочку»? Я представляю новый MaterialShell , описываю, как я хочу, чтобы мое приложение было структурировано и выглядело, и просто запускаю его, чтобы увидеть новые возможности?

Настройка

Какие у меня есть варианты, если мне нравится, как выглядят Flyout или пункты меню, но мне нужно настроить их, чтобы они соответствовали композициям моих дизайнеров? В какой момент я говорю: «Ух, я должен был все это сделать сам» и перемещаю все, что у меня есть, в стандартную структуру приложения Xamarin.Forms?

Если мне придется полностью отказаться от MaterialShell , я потеряю все эти стилистические достоинства и вернусь к тому месту, где начал (как сегодня), с Entry выглядят совершенно иначе между iOS и Android и UWP ? Я бы не хотел.

Я жду переломного момента. После того, как я воспользуюсь этим подходом, чтобы быстро приступить к работе, я столкнусь с некоторыми ограничениями, и мне нужно будет изучить свои варианты. Что это такое и в какой момент мне лучше не использовать MaterialShell ?

Эта проблема

Я закрою этот первый комментарий несколькими вопросами для всех, кто читает.

  • Хорошо ли определена проблема, которую пытается решить это предложение?
  • Вы разделяете эту проблему?
  • Читая эту спецификацию, с какими проблемами вы столкнулись в предыдущих проектах, как вы думаете, это решит для вас?

Если возможно, скриншоты / дизайнерские изображения сделают еще лучше.

Также проверьте это:

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

@jassmith Было бы здорово, если бы вся идея была представлена ​​в виде изображений. Престижность усилий по размещению спецификаций. Мои вопросы могут быть неправильными.

Мои запросы

  • Поддержка планшетов, отзывчивость приложений, адаптирующихся к разным макетам, не рассматривается.
  • Будет ли сложным переход от текущей модели к новой? С точки зрения разработчика приложений и участников Xamarin Forms.
  • Я согласен с тем, что для большей части приложения требуется единый пользовательский интерфейс (потому что количество настраиваемых средств визуализации, которые мы должны написать когда-нибудь для достижения тех же концепций пользовательского интерфейса) без учета специфики платформы, удалит ли новое направление все существующие функции, например, будем ли мы по-прежнему разрабатывать Xamarin.Forms приложения с пользовательским интерфейсом, зависящим от платформы, или все будут вынуждены перейти на новые стандарты.
  • Будут ли концепции рендерера по-прежнему существовать внутри MaterialShell
  • Можем ли мы на самом деле сказать, что в iOS мы хотим, чтобы это отображалось таким образом? У Flutter есть стили Купертино (пользовательский интерфейс Apple), которые работают в Android, и пользовательский интерфейс Android, который работает в iOS. В каком направлении будет двигаться Xamarin Forms. Будет ли у разработчика такие возможности, которые предлагает сейчас флаттер.

Будет ли это также включать что-то вроде TextInputLayout для поддержки плавающих меток / заполнителей, а также сообщений об ошибках? Если да, то я думаю, что Binding следует расширить, включив в него ValidateOnDataErrors, аналогичные wpf.

Смотрите мою реализацию здесь
https://github.com/XamFormsExtended/Xfx.Controls/blob/develop/src/Xfx.Controls/XfxBinding.cs

Кроме того, мне интересно, должен ли MaterialShell расширять Shell, чтобы можно было создать HumanInterfaceShell для внешнего вида iOS.

@ChaseFlorell, это

@davidortinau , @jassmith ,

Спасибо, что составили эту спецификацию и позволили нам оставить отзыв.

Хорошо ли определена проблема, которую пытается решить это предложение?

да. Система навигации не полностью разработана в Xamarin Forms, поэтому остается открытым вопрос о том, как ее заполнить или вообще обойти.

Вы разделяете эту проблему?

да.

Читая эту спецификацию, с какими проблемами вы столкнулись в предыдущих проектах, как вы думаете, это решит для вас?

Я собираюсь ответить на этот вопрос, сказав, что не думаю, что это решит проблемы. Наши особые проблемы заключаются в том, что нынешняя навигационная система слишком жесткая, а не в том, что она недостаточно жесткая. Самым ярким примером для нас является TabbedPage. Нет представления TabbedView, поэтому, если нам нужны вкладки в нашем приложении, мы должны использовать TabbedPage. Таким образом, TabbedPage должен занимать весь экран, и мы не можем использовать пространство для собственных кнопок или других элементов управления, которые мы могли бы разместить на экране. Я бы порекомендовал переместить больше функций _за_страниц и вниз в представления, а не перемещать функциональность в страницах на еще более высокий уровень.

Такие вещи, как FloatingMenu и FlyoutBehavior пугают меня, потому что они подразумевают, что навигация будет жестко закодирована в системе Xamarin.Forms, и дальнейший контроль будет отнят у разработчиков программного обеспечения. Я вижу некоторую ценность в более стандартизированном подходе, но за это определенно придется заплатить.

Мы всегда работали с другими технологиями на основе XAML, такими как Silverlight, WPF и UWP. В этих технологиях у нас гораздо более открытый подход, когда мы можем больше определять, как работает навигация. Недавно мы привлекли консультанта по UI / UX. Он не подозревал о причудах XF. Мы просто попросили его создать нам несколько экранов на основе функциональности нашего программного обеспечения. Большая часть того, что он рекомендовал, не могла быть реализована из-за таких вещей, как отсутствие TabbedView. Я боюсь, что вместо того, чтобы упростить навигацию, произойдет то, что этот фреймворк на самом деле усложнит реализацию дизайнов, предоставленных нам дизайнерами UX / UI.

Еще я бы сказал, что эта структура выглядит беспрецедентной для других платформ XAML, и я бы сказал, что приоритет должен быть на обеспечении стандартизации для всех платформ, а не на предоставлении новых структур, с которыми другие платформы не будут совместимы. В настоящее время мы создаем для трех платформ: Silverlight, Xamarin.Forms и WPF. Что нам нужно, так это стандартизация этих платформ, чтобы создавать меньше отклонений, а не больше.

@dylanberry ,

Другое дело, если мы хотим писать собственные оболочки для удовлетворения конкретных потребностей пользовательского интерфейса.

да. Это меня беспокоит. У каждого приложения есть свои конкретные варианты использования, и большая жесткость, вероятно, сделает его сложнее, а не проще реализовать.

Есть и такая проблема: https://github.com/xamarin/Xamarin.Forms/issues/2452#issuecomment -380991817

Я повторю сказанное выше, а также спрошу, как жесты и указатели будут работать с примитивами форм?

Общий комментарий заключается в том, что для каждой строки кода, добавляемой в систему, существует 3+ шанса на добавление ошибочного кода. В Xamarin Forms уже есть много ошибок, которые необходимо исправить. Больше кода означает, что вероятность добавления ошибок возрастает в геометрической прогрессии. Багов будет больше. Я считаю, что команда XF должна работать над уменьшением размера базы кода, а не над ее увеличением. Уменьшение базы кода - единственный способ снизить вероятность появления ошибок.

Зачем снова изобретать что-то новое, вместо того, чтобы исправлять существующие ошибки и сначала убедиться, что все в порядке?

Для меня это было затронуто, но навигация является самым большим камнем преткновения в Xamarin Forms и вызвала у меня самые сильные боли за последние три года.

Навигация не согласована на всех трех платформах с шаблоном MasterDetail, что вызывает много проблем с гамбургером, вынуждающим вас нажимать модальные страницы, затем вам нужно реализовать настраиваемую панель навигации, поскольку вы не можете добавить назад, но анимация выглядит ужасно на Android (даже в МД).

  • В идеале во многих случаях вы должны иметь возможность отказаться и переопределить содержимое панели навигации своим собственным ContentView. PlatformSpecifics изначально обсуждалась как что-то, что позволяло бы позиционировать элементы панели инструментов (еще когда я разговаривал с Брайаном), но оказалось, что это что-то ограниченное использование.

  • Возможность переопределить такие вещи фреймворка, как анимация всплывающих страниц.

Многое из того, что предлагается, кажется очень полезным. Пока вы можете просто использовать оболочку материала на определенных страницах, и это не касается всего приложения, код будет действительно полезным. Это определенно то, что мы будем использовать, потому что в настоящее время я постоянно говорю нашему UX-специалисту: «Это ограничение Xamarin Forms» (как я делал в своей предыдущей роли). Осмелюсь сказать, мы должны получить обратную связь с точки зрения UX, которые ранее использовали стили для приложений Forms. Он должен быть включен, как XamlC.

Не уверен насчет названия, FlexShell имело бы больше смысла ... но теперь у нас есть Flexbox (хотя мы никогда не просили об этом ... извините, Дэвид, ничего не мог с собой поделать 😄)

Кроме того, будет ли это означать, что темы мертвы? в любом случае никогда ими не пользовался.

@mackayn

Это определенно то, что мы будем использовать, потому что в настоящее время я постоянно говорю нашему UX-специалисту: «Это ограничение Xamarin Forms» (как я делал в своей предыдущей роли).

Хорошо, но не имеет ли смысла исправлять или улучшать текущую реализацию вместо создания совершенно новой, которая также будет иметь ошибки и ограничения? Здесь сказано, что:

MaterialShell - это категоричный API "

Серьезно, в скольких разных направлениях могут идти Xamarin Forms? Команда XF едва может продолжать исправлять текущую реализацию XF по крайней мере для Android и iOS, а что теперь? Как насчет исправления ошибок, исправления предварительного просмотра XAML, как насчет производительности?

Кто-то открыл тикет с предложением добавить простую, но очень полезную поддержку кроссплатформенной твердой и градиентной кисти, но @jassmith ответил, что это будет проблематично. Но теперь этот билет предлагает то же самое .... Как это больше не проблема? Иди на фиг

@opcodewriter

Да, я говорил, что в течение последнего года есть странности навигации, которые сдерживают, например, команду Prism, и они никогда не могли решить проблемы.

На данный момент я просто пытаюсь предложить конструктивную обратную связь, хотя Xamarin Forms находится на критическом этапе своего развития, этот API может решить многие из проблемных точек, если он будет реализован гибким способом, а не подходом для всего приложения.

@jassmith означает ли это, что XF примет подход Flutter (с использованием механизма рендеринга вместо собственных элементов управления) для Shell?

Ребята, вчера мы с Джейсоном обсуждали, как улучшить эту спецификацию, и мы будем делать большое обновление, мы разбиваем это на разные проблемы.

Я хотел бы повторить некоторые из вышеупомянутых мнений: пожалуйста, давайте просто улучшим то, что у нас есть, если, конечно, у вас нет безграничных ресурсов, тогда действуйте 😉

Так много чего еще не сделано: исправление ListView (трудно поверить, что это все еще не работает должным образом), реализация элементов управления, таких как CheckBox, RadioButton, реализация поддержки кистей (SolidColorBrush, GradientBrush), возможность отображать всплывающие окна на основе страницы или ContentView, исправление ошибок (см. недавние сообщения об ошибках в прозрачных представлениях), производительность, инструменты и многое другое ....

Зачем вам начинать что-то новое ?????

@TonyHenrique Да, картинки были бы отличными. К сожалению, я не художник и не владею правами на изображения, которые использую для справки. Я надеюсь, что у кого-то из членов команды дизайнеров будет время помочь мне создать правильные изображения для спецификации.

@muhaym

  • Поддержка планшетов. Он предназначен для адаптации макета к планшетам. Конечно, это не касается случаев размещения внутри ваших страниц с контентом, это будет другая функция. В основном я бы справился с этим с новым VSM.
  • В основном просто поместите ваши ContentPages в нужное место и адаптируйтесь к новым концепциям навигации. Не скажу, что это всегда будет тривиально, но и не должно ослаблять.
  • Абсолютно не удаляю никаких функций. Фактически, я работаю над обновлением спецификации, чтобы включить базовый класс Shell, в котором отсутствуют некоторые функции MaterialShell, но в остальном он является версией пользовательского интерфейса Shell для конкретной платформы.
  • да. Добавление чертежа просто меняет то, какой рендерер вы получаете, на что-то, что известно, как обрабатывать рисунок.
  • да. Вы можете поменять местами, какой рендерер будет использоваться на любом уровне иерархии. Рендереры просто меняются шаблонами, задаваемыми специальными ключами в словарях ресурсов. Вы можете изменить эти шаблоны на все, что захотите, или отключить их, установив для них значение null.

@ChaseFlorell нет, но я открыт для предложений, если вы хотите приложить поправку к спецификации. Что касается Shell vs MaterialShell, я уже говорил об этом выше. Шаг 1 - убедиться, что MaterialShell имеет смысл, а затем разбить его на базовый класс - шаг 2.

@dylanberry базовый класс не сделает это намного проще. Это не так просто, как изменить DrawingTemplates. Я намереваюсь реализовать этот аспект MaterialShell в коде платформы для оптимальной производительности.

Здесь появятся жесты

@mackayn API переходов / переходов скоро появится здесь. Я все еще прорабатываю некоторые из своих первоначальных предложений по именованию. Это, безусловно, будет происходить поэтапно, и только переходы страниц будут в фазе 1. Однако это позволит вам переопределить анимацию фреймворка. Что касается подписки. Оболочка должна быть корнем вашего приложения и не может содержать ничего, кроме TemplatedPage. Тем не менее, тематика внутреннего контроля находится на 100% под вашим контролем. Это немного больше, чем волшебный переключатель для включения / выключения новых шаблонов, и вы можете управлять этим переключателем так же, как и мы. Это позволяет вам включать и отключать темы на странице, макете или даже на уровне управления.

@ encrypt0r не совсем так. Думайте об этом как о гибриде. Это позволит выполнять рендеринг, но под капотом все элементы управления, специфичные для платформы, просто тематические с кодом рисования. Однако в Skia есть аварийный люк, который можно легко добавить (хотя я сомневаюсь, что он приближается к версии v1).

@opcodewriter ListView2 (очевидно, что он на самом деле так называться не будет) и TemplatedItemsList, хотя они хорошо работали для того, что они предназначались для 1.0, далеки от того, что им нужно для современного использования API.

К сожалению, я не могу придумать, как решить эту проблему в самом типе ListView, и, к сожалению, не думаю, что сообществу удалось это сделать. Лучший вариант прямо сейчас - оставить ListView таким, какой он есть, а затем сделать что-то гораздо более гладкое, с меньшими накладными расходами, меньшими объемами бухгалтерского учета, менее странными типами, которые не должны существовать, и доверить целевым фреймворкам то, что они делают лучше всего.

Простое удаление старой стратегии утилизации, что было бы огромным изменением, нарушающим обратную совместимость, которое мы не можем сделать, приведет к удалению значительной части кодовой базы Xamarin.Forms. ListView2 приблизит вас к металлу, удалив эти элементы, которые должны были быть ограждениями (или, в случае Cell, нечестивым слиянием двух разных внутренних проектов) и теперь просто причиняют вред всем.

Старая стратегия кэширования влияет на КАЖДЫЙ существующий сегодня рендерер. Это причина, по которой каждый рендерер поддерживает изменение своего элемента. Если это исчезнет, ​​по моим оценкам, исчезнет около 10% всего кода в проекте. Это действительно самая большая опухоль в проекте.

@davidortinau, ты получаешь свой собственный комментарий только потому, что у тебя такое красивое форматирование!

Если я использую этот подход для описания своего приложения на верхнем уровне, я получаю:

  • тематическое приложение, которое будет выглядеть одинаково на всех платформах
  • материальный дизайн (в данном случае) выкройки включены по умолчанию
  • новейшие шаблоны навигации, включенные с конфигурацией
  • Мне не нужно трудиться, чтобы настроить Entry или Button, чтобы они выглядели одинаково на iOS, Android и UWP?

Это точно? Другие преимущества, которые я должен выделить?

Да, это правильно. Вы можете выделить множество других преимуществ, но они станут очевидными, как только вы начнете с этим связываться. Как вы можете делать нижние листы, иметь FAB, перемещаться по URL-адресам (обновление все еще идет) и многое другое.

Вместо приложения у меня есть MaterialShell. Мне нужно изучить / принять новую парадигму приложения верхнего уровня, чтобы извлечь из этого пользу?

Неправильный. MainPage ваших приложений - это MaterialShell. Приложение по-прежнему является вашим корневым каталогом.

Как только я вхожу в свое приложение, я снова нахожусь в стране ContentPage, верно? Но все мои кнопки и входы материалистичны и красивы.

За исключением того, где вы ошибались выше, да, это правильно.

Могу ли я по-прежнему использовать OnPlatform и тому подобное, чтобы внешний вид (или поведение) отличался на другой платформе?

да.

Как выглядит мой путь миграции из существующего приложения в эту «оболочку»?

Взгляните на репро-кейс Google Play Store, представьте, что вы помещаете туда все текущие страницы ваших приложений. Это заменяет только те области в вашем приложении, где вы напрямую используете страницы Nav / Tab / MD. Это не влияет на ваши ContentPages.

Я представляю новый MaterialShell, описываю, как я хочу, чтобы мое приложение было структурировано и выглядело, и просто запускаю его, чтобы увидеть новые возможности?

Бинго

Какие у меня есть варианты, если мне нравится, как выглядит всплывающее меню или элементы меню, но мне нужно настроить их, чтобы они соответствовали композициям моих дизайнеров?

Вы полностью контролируете заголовок, как он сворачивается и скрывается. Вы полностью контролируете внешний вид каждой из «Ячеек» (они не будут ячейками) во всплывающем меню. Вы также полностью контролируете заголовок для каждой группы. По сути, вы управляете "внешним видом" всего, но нам все равно нужно добавить пару дополнительных мест, чтобы вы могли разместить дополнительный контент.

В какой момент я говорю: «Ух, я должен был все это сделать сам» и перемещаю все, что у меня есть, в стандартную структуру приложения Xamarin.Forms?

Если всплывающее окно физического макета Google Play Store выглядит совершенно иначе, чем вы хотите. Не совсем другой, совершенно другой.

Если мне придется полностью отказаться от MaterialShell, потеряю ли я все эти стилистические достоинства и вернусь к тому месту, где начал (как сегодня), когда Entry выглядит совершенно по-разному между iOS, Android и UWP? Я бы не хотел.

Нет MaterialShell просто устанавливает некоторые ресурсы по умолчанию, чтобы их дети получали их. Вы сможете сделать это сами. Возможно, вам все равно придется это сделать, на самом деле мы не взяли на себя обязательство заставлять MaterialShell делать это по умолчанию. Если мы сделаем подписку вместо отказа, это будет единый вызов API для любого поддерева.

Я жду переломного момента. После того, как я воспользуюсь этим подходом, чтобы быстро приступить к работе, я столкнусь с некоторыми ограничениями, и мне нужно будет изучить свои варианты. Что это такое и в какой момент мне лучше не использовать MaterialShell?

Намерение состоит в том, что вам НИКОГДА не лучше отказываться от Shell. Возможно, вам не нужен материал, но вы всегда должны хотеть Shell (снова идет базовый класс Shell). Почему? Внешний вид оболочки будет гораздо более настраиваемым, история навигации будет гораздо более унифицированной, не должно быть ничего разумного, что вы можете сделать с другими страницами, что вы не можете сделать с Shell.

Более того, цель состоит в том, чтобы убедиться, что средства визуализации Shell действительно легко настраиваются и работают нормально. Никаких волшебных скрытых классов, никаких кастомных подклассов нативных представлений, над которыми мы серьезно работаем. Насколько это возможно, каждый компонент рендереров будет скомпонован и заменен. Таким образом, если он не работает так, как вы хотите, вы можете исправить это ...

Почему мы не сделали этого сначала? Вначале это не было целью дизайна, а потом мы просто поженились с этим ... Он достаточно большой и достаточно новый, чтобы нам не нужно было таскать эту ошибку с собой.

@opcodewriter

Серьезно, в скольких разных направлениях могут идти Xamarin Forms? Команда XF едва может продолжать исправлять текущую реализацию XF по крайней мере для Android и iOS, а что теперь?

Как насчет исправления ошибок, исправления предварительного просмотра XAML, как насчет производительности?

^^ Это

@migueldeicaza

Ребята, вчера мы с Джейсоном обсуждали, как улучшить эту спецификацию, и мы будем делать большое обновление, мы разбиваем это на разные проблемы.

Мигель, это явно будет большая работа. Я не могу говорить от имени всех разработчиков, но могу сказать вам, что моя команда хочет трех вещей: стабильности, производительности и гибкости. Мы хотим исправить ошибки. Мы хотим, чтобы наше приложение работало бесперебойно, и мы хотим иметь возможность реализовывать дизайн, который дают нам наши UI / UX-дизайнеры, не оборачиваясь и не говоря: «Извините, это просто невозможно на нашей платформе». Эта спецификация, похоже, противоречит этой цели. Это потребует дополнительных ресурсов, затраченных на работу, а это означает, что ваши ресурсы не будут высвобождены для работы над стабильностью, производительностью и гибкостью.

Будет ли это новым поведением / способом разработки по умолчанию в формах xamarin? Или у нас все еще будет возможность создавать наши приложения с учетом особенностей каждой платформы?

@DanielCauser, хотя я подозреваю, что в конечном итоге это может стать способом "по умолчанию", это никоим образом не заменит текущий способ. Это будет просто более интегрированный и современный способ, который предоставит гораздо больше оболочки, которую люди по умолчанию создают вручную. Вдобавок ко всему, поскольку мы будем предоставлять оболочку как единый элемент управления, мы можем многое оптимизировать в отношении ее рисования и компоновки. У вас больше не будет трех проходов рисования только для вашей оболочки.

Я осторожно поддерживаю эту идею, при условии, что предлагаемые улучшения прорабатываются посредством улучшений в базовом коде Xamarin Forms. Если это добавит сложности к формам, я бы не стал его использовать.
За свои деньги я бы предпочел, чтобы ресурсы разработчиков были направлены на то, чтобы сделать формы более гибкими, быстрыми и законченными, чем сейчас. Если бы это произошло, я мог бы сделать все предлагаемые новые функции здесь для себя. DIY в этом случае почти наверняка подойдет мне и моим клиентам лучше, чем общий набор инструментов, предоставляемый Xamarin, каким бы хорошим он ни был. За некоторыми заметными исключениями это предложение не решает проблем, с которыми я сталкиваюсь в настоящий момент.

@jassmith

  1. Есть более 500 открытых выпусков.
  2. Xamarin Forms исполнилось 3 года, и все еще есть ошибки в основных элементах управления и функциональности, по-прежнему отсутствуют важные функции, а производительность еще не полностью улучшена (я знаю, что были внесены некоторые улучшения, но производительность на Android заметно ниже).
  3. Команда разработчиков Xamarin Forms все еще невелика.

Почему вы хотите начать работать над этой новой функцией прямо сейчас? Не имеет смысла сначала сосредоточиться на вышеизложенном?

По поводу вашего комментария выше, относящегося к ListView: я приветствую любой смелый подход к нему, включая его полную переделку \ замену. Не похоже, что в Xamarin Forms все так здорово, вещи нельзя трогать \ менять.

@opcodewriter

1) Ага, есть. Я согласен, что это проблема, и я буду продолжать оставаться приоритетной задачей, к которой я лично стремлюсь.

2) Производительность на Android - одна из основных причин этого. Это дает фреймворку больше времени для перехода между страницами, поэтому мы можем скрыть такие вещи, как время JIT. Мы можем упреждающе загружать и сохранять страницы гораздо более разумно. Что команда XF не может исправить, так это общее время JIT. Если вы запускаете свое приложение на Android с включенным AOT и оно работает намного быстрее, я ничем не могу вам помочь.

3) Никаких аргументов.

Почему вы хотите начать работать над этой новой функцией прямо сейчас? Не имеет смысла сначала сосредоточиться на вышеизложенном?

Эта работа не запланирована, мы просто обсуждаем здесь спецификацию. Мое руководство будет планировать его, когда посчитает нужным с моим советом.

По поводу вашего комментария выше, относящегося к ListView: я приветствую любой смелый подход к нему, включая его полную переделку \ замену. Не похоже, что в Xamarin Forms все так здорово, вещи нельзя трогать \ менять.

ListView действительно является источником ошибок Xamarin.Forms. Из этих 500 проблем, 220 из которых помечены как ошибки (есть также много проблем с обслуживанием или улучшением), к северу от 25% относятся только к ListView. Для сравнения, это примерно тот же процент, что и для всей платформы UWP. Хуже того, изрядное количество сбоев в Android, которые в основном описываются как средство визуализации, используемое после удаления, также являются ошибками ListView, однако они вряд ли появятся в моем поиске, поскольку ListView нигде не будет отображаться в поисковом запросе.

@jassmith помимо исправления существующих проблем (помимо ListView есть и другие вещи, которые все еще не всегда работают правильно), есть также важные функции, которые были упущены (случайный порядок):
- Настоящая поддержка всплывающих окон (базовая и общая функция все еще отсутствует)
- Отменить навигацию по страницам при переходе назад (давно нерешенная проблема)
- Отсутствуют основные элементы управления (нет CheckBox, RadioButton и т. Д.)
- Кросс-платформенное рисование (Canvas control или другой способ)
- Поддержка кроссплатформенного рисования сплошных \ градиентных кистей (SolidColorBrush, GradientBrush)

Я бы хотел, чтобы больше работ было сделано в направлении действительно более богатого фреймворка, а не добавлялись такие вещи, как стиль CSS или Flexbox (которые имели свои собственные проблемы).

@opcodewriter

Настоящая поддержка всплывающих окон (базовая и общая функция все еще отсутствует)

Справедливо, кажется, что этому никогда не уделяется достаточно внимания, чтобы стать реальностью. В какой-то момент это действительно зашло довольно далеко.

Отменить навигацию по страницам при переходе назад (давно нерешенная проблема)

На самом деле это то, для чего предназначена MaterialShell. Есть довольно веские причины, по которым этого нельзя сделать в NavigationPage.

Отсутствуют основные элементы управления (нет CheckBox, RadioButton и т. Д.)

Некоторые из них являются частью инициативы F100, которая реализуется сейчас.

Кросс-платформенное рисование (Canvas control или другой способ)

Это будет родственный API для этого, как указано в # 2452.

Поддержка кроссплатформенного рисования сплошных \ градиентных кистей (SolidColorBrush, GradientBrush)

Тот же ответ, что и выше.

@jassmith

Справедливо, кажется, что этому никогда не уделяется достаточно внимания, чтобы стать реальностью. В какой-то момент это действительно зашло довольно далеко.

Хорошо, с нетерпением жду его приоритетности к концу 2018 года :)

На самом деле это то, для чего предназначена MaterialShell. Есть довольно веские причины, по которым этого нельзя сделать в NavigationPage.

Не могли бы вы подробнее рассказать, почему этого нельзя сделать в текущей реализации?

Некоторые из них являются частью инициативы F100, которая реализуется сейчас.

Понятно. Скрещенные пальцы..

Не могли бы вы подробнее рассказать, почему этого нельзя сделать в текущей реализации?

Я не буду здесь вдаваться в подробности, потому что мы сильно сбились с пути, но суть такова:

  • Вы не можете отменить жест обратного смахивания в iOS реактивно. Поскольку это основной метод, который люди используют для возврата к более крупным телефонам, это становится явным упущением.
  • Хотя технически возможно переопределить это поведение в iOS, для этого требуется достаточно глубоко изучить внутреннее устройство UINavigationController таким образом, чтобы мы не могли быть уверены, что он действительно будет поддерживаться или работать, когда выйдет новая версия iOS. Короче говоря, Apple, похоже, не очень-то нравится, что люди этим занимаются.

Есть и другие незначительные проблемы, связанные с тем, как это влияет на стиль. Однако это короче. Если вы все еще хотите обсудить эту особенность, предлагаю открыть новый выпуск :)

@jassmith
Я думал, что достаточно просто обработать gestureRecognizerShouldBegin и вызвать что-то вроде OnBackButtonPressed .

В целом мне очень нравится многое из того, что я читаю, однако это не похоже на то, что следует делать в ядре nuget / репозитория Xamarin Forms.

Это упрямый подход, который должен быть построен на основе Xamarin Forms, а не встроен в него. Я рассматриваю это как отдельную библиотеку, которая позволяет разработчикам использовать другой подход. Обязательные части Xamarin Forms, которые необходимо предоставить, должны быть, и это должно быть построено на основе этих битов.

Точно так же, как когда разработчики принимают решение использовать Xamarin Classic / Native или Xamarin Forms, я вижу аналогичное решение использовать Xamarin Forms или Xamarin Forms with a Shell.

Xamarin Forms должны сосредоточиться на создании лучшей кроссплатформенной инфраструктуры пользовательского интерфейса, не пытаясь согласовать платформы, чтобы они выглядели как друг друга. Сегодня Xamarin Forms отлично справляется с задачей обеспечить уважение к платформе.

Я мог видеть базовую оболочку, находящуюся в репозитории Xamarin Forms, и некоторый код для обработки оболочек, но Материальная оболочка кажется слишком тесно связанной с определенным языком дизайна и шаблоном навигации, чтобы я мог подумать, что она должна быть в репозитории Xamarin Forms.

@MisterJimson
Спасибо за ваш отзыв. Точное размещение общедоступной поверхности API еще не определено. У обоих подходов есть свои плюсы и минусы.

Спецификация будет обновлена ​​(надеюсь, очень скоро), и в ней будут присутствовать классы Shell и MaterialShell. Класс MaterialShell будет той частью, которую мы рассматриваем как выход из ядра. Shell будет тем, что вы описали.

Обновлено с обновлением Shell Breakout и навигации.

Мне бы очень хотелось, чтобы существующая реализация XF была сделана ... сильнее и лучше, чтобы что-то подобное могло существовать как надстройка, а не как часть BCL. Таким образом, наличие надежной базовой платформы, которая является правильной и стабильной, принесет пользу существующим приложениям и любым новым уровням, подобным этому.

С нетерпением жду развития этой вещи.

@jassmith @brianlagunas

Всего несколько наблюдений.

  • BackButtonBehavior, обязательно должно быть свойство видимости на случай, если оно вам вообще не нужно?
  • Схема навигации в материальной оболочке похожа на Prism, будет ли она работать с этими существующими фреймворками? (Призма, FreshMVVM, MVVMCross)
  • Можете ли вы полностью переопределить макет на панели навигации? в нынешнем виде Forms чрезвычайно ограничены в этом отношении, и вы получаете неуклюжие панели навигации, которые заставляют вас идти по маршруту customrenderer, будучи уверенным в том, что новая версия Forms, скорее всего, сломает ваш пользовательский код.
  • MasterDetail особо не затрагивается, сможете ли вы настроить всплывающее меню?
  • Как мы будем контролировать гамбургер?

Я просто хочу убедиться, что существующие болевые точки и ограничения устранены, а новые имеют новые возможности.

Звучит здорово.

Я новичок в XF, но фреймворк имеет репутацию хрупкого, хотя, безусловно, он быстро улучшается благодаря вашим усилиям.

Так что это мое мнение :-)

Здорово , что Xamarin сейчас очень любят, но я согласен с справиться с

Мне также нравятся мысли @MisterJimson о том, что это должен быть другой уровень, но вы должны быть честны с собой относительно своих возможностей и того, сколько фреймворков вы можете поддерживать. Мы все склонны кодировать новые захватывающие блестящие вещи и избегать сложных решений, но мы полагаемся на вас, чтобы разработать прочную основу для нашего кода.

У меня достаточно проблем с тем, чтобы мой код работал, не беспокоясь о чужом :-)

XF сейчас находится в хорошем положении, у него есть потенциал, чтобы стать действительно надежным набором инструментов.

Спасибо за всю вашу тяжелую работу, это видно.

@mackayn

BackButtonBehavior, обязательно должно быть свойство видимости на случай, если оно вам вообще не нужно?

Установите команду с CanExecute, возвращающим false. Я решил пока не добавлять вторичный метод.

Схема навигации в материальной оболочке похожа на Prism, будет ли она работать с этими существующими фреймворками? (Призма, FreshMVVM, MVVMCross)

Я очень на это надеюсь! Я не уверен, но я думал о них и обо всех их проблемах. Вот почему, например, вся навигация происходит через одно событие.

Можете ли вы полностью переопределить макет на панели навигации? в нынешнем виде Forms чрезвычайно ограничены в этом отношении, и вы получаете неуклюжие панели навигации, которые заставляют вас идти по маршруту customrenderer, будучи уверенным в том, что новая версия Forms, скорее всего, сломает ваш пользовательский код.

Эта часть сложнее. Я хотел бы предоставить здесь как можно большую расширяемость, но я действительно открыт для предложений о том, как улучшить это разумным и разумным образом.

MasterDetail особо не затрагивается, сможете ли вы настроить всплывающее меню?

Вы можете установить заголовок для любого произвольного представления, вы управляете шаблоном, используемым для заголовков и элементов групп, а также можете добавлять элементы меню. Вы контролируете некоторые аспекты макета, но не на 100%. Опять же, было бы хорошо подумать о том, что еще, по вашему мнению, вам нужно. Я ясно вижу необходимость в нижнем колонтитуле со свойством поведения нижнего колонтитула.

Как мы будем контролировать гамбургер?

BackButtonBehavior также отменяет гамбургер. Возможно, его стоит переименовать. Я снова открыт для предложений. Первоначально я называл его LeftBarButton, но в ситуациях с RTL его нет слева ...

Техническая окупаемость @stevehurcombe продолжается и продолжается. Параллельно с этим будет работать гораздо меньший состав команды. К сожалению, реальность такова, что во многом эта спецификация странным образом связана с технической окупаемостью. Xamarin.Forms понес огромную задолженность по API с выпуском 1.0 и с тех пор несет эту задолженность. Определенные вещи в XF очень сложно заставить работать правильно или даже невозможно сделать правильно просто из-за того, как их выражает API.

Одной из таких областей является тесное взаимодействие между панелью вкладок и панелью навигации, а также обеспечение отсутствия сбоев при перемещении между вкладками или элементами в MDP. Есть много областей, где будут возникать небольшие заминки, потому что каждый элемент не может получить целостное представление о оболочке вашего приложения.

Что касается инструментов, для этого есть отдельная команда, и они делают огромные успехи. Внутренний инструментарий значительно улучшился за последние 6 месяцев, и я очень надеюсь, что вы попробуете это!

@mackayn

Схема навигации в материальной оболочке похожа на Prism, будет ли она работать с этими существующими фреймворками? (Призма, FreshMVVM, MVVMCross)

Не бойтесь, @jassmith обратил мое внимание на это до того, как сообщество осознало, что проблема здесь ... так что я могу с некоторой уверенностью сказать, что это проблема, которую он, безусловно, заботит так же, как и мы. Вы можете быть уверены, что мы надеемся поддержать это. Что-то такого масштаба, безусловно, потребует большого количества диалогов между командами, чтобы убедиться, что оно отвечает потребностям разработчика форм в целом, а также удовлетворяет потребности фреймворков MVVM, таких как Prism.

@dansiegel

Приятно знать, что обе команды ведут диалог, это все, что мне нужно было знать 👍

@jassmith К настоящему времени очевидно, что некоторые вещи работают или были
Я видел, как PR отвергался с хорошим рефакторингом, потому что «мы не хотим такого рода изменений». Я не уверен, кто установил это правило, но ему следует сделать глубокий вдох, расслабиться и, возможно, пересмотреть «правило».
Что лучше: продолжать расстраивать разработчиков, использующих фреймворк, который не справляется с этим, или разочаровывать разработчиков, которым необходимо провести некоторую работу по рефакторингу? Только мои 2 цента ...

@opcodewriter мы с вами согласны, но это оффтоп для данной спецификации.

Просто прочтите новый материал по навигации, и он мне очень понравится. Мне нравится иметь умную руку для привязки навигационных команд, и ориентировать навигацию по URL-адресам (например, и я предполагаю, что на нее повлияла Prism) - это разумно.

По иронии судьбы схема навигации URI была тем, что мы хотели сделать еще в тот день и начали подталкивать Prism к реализации, потому что мы не могли разумно включить ее в структуру. Чтобы не брать на себя их заслугу, они заслуживают 100% этого :)

Точная семантика сокращений все еще не известна.

Я думаю, это скорее всего закончится так:

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

или

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

Таким образом, расширения могут более точно определять, какие параметры они принимают. Пространство имен используется в основном для упрощения поиска с помощью intellisense.

@jassmith Мне очень нравится этот переход. Могу я спросить, как вы собираетесь поддерживать push-модальное окно?

У меня нет всех подробностей, но я мог бы представить себе url nav точно так же, как призму, заключенную в расширения разметки.

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

Прежде всего следует отметить, что навигация по URI будет работать только с Shell. Это единственное место, где мы можем последовательно разобраться в стеке, не имея странных крайних случаев, и мы можем спроектировать навигационные взаимодействия для поддержки этой концепции.

На данный момент мы поддерживаем только полные URI. С частичными вещами работать намного сложнее, потому что они контекстуальны.

Тогда ваши 3 примера будут, если текущее местоположение: app: // Shell / Apps / Games / Details

В частности, это означает, что вы находитесь в оболочке, у которой текущий ShellItem имеет маршрут приложений, у которого текущий ShellTabItem имеет маршрут Games, у которого ContentPage помещен в свой стек, который имеет сведения о маршруте.

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

В оболочке uri первым расположением всегда является оболочка. Если это не так, предполагается, что это модальный толчок. Далее идет ShellTab, затем ShellTabItem. После этого следует стек навигации ShellTabItem. На данный момент у меня нет намерения переносить навигацию URI во все возможные элементы управления страницей. Это ДЕЙСТВИТЕЛЬНО раздражает людей, которые используют MasterDetailPage ...

С помощью свойств Route Registration и Route нет необходимости в маршрутизации на основе типа. Я собираюсь удалить его из спецификации.

@jassmith больше задумывается об этой навигации, и у меня есть несколько вопросов

  1. как ты справишься с CanExecute
  2. как вы можете дать пользователю возможность контролировать (предотвращать чтение) несколько нажатий?
  3. как вы справляетесь с относительной навигацией? Т.е. у вас 3 страницы в глубину, и вам нужно перейти на четвертую, но стек полностью динамический?
  4. В prism есть фантастическая идея NavigationParameters посредством которой мы можем передавать не только базовые значения через строку запроса /Navigation/MyPage/MyPageDetails?id=33 , но и сложные объекты new NavigationParameters {{nameof(MyObject), MyObject}} . Планируете ли вы поддерживать что-то подобное?

@ChaseFlorell

1) С переходами? В настоящее время вы не можете. Определенно нужно подумать о большем. Есть способ сделать команду перехода, но это ... отстой. Это позволит вам справиться с этим, но в тот момент это ДЕЙСТВИТЕЛЬНО того не стоит.

2) Переход отключится, пока не завершится отправка. Дальнейшие попытки активировать команду no-op до завершения предыдущей задачи навигации.

3) Вы можете использовать традиционную навигацию, такую ​​как push / pop с переходами. Это относительные действия.

4) [QueryParameterAttribute] может уже существовать, а может и не существовать, я не могу ни подтвердить, ни опровергнуть. ;)

Вряд ли мы добавим поддержку сложных объектов. Идея состоит в том, что вы используете конвертеры, чтобы принимать простые значения и превращать их в сложные объекты.

Из прошлого опыта здания URI на основе приложений навигации (обратно в CAB-Composite UI Application Block для р и р), я настоятельно рекомендую вам не использовать System.Uri типа и вместо того, чтобы просто сделать все выглядеть как URI, но не использовать саму реализацию URI. @pprovost может свидетельствовать о шрамах жизни, которые, должно быть, оставила в нем работа. Я помню, как столкнулся с бесчисленным множеством проблем, когда мы столкнулись с ограничениями и ошибками интернет-URI (например, с именами хостов), о которых нам было наплевать на вещи внутри приложения.

Полагаю, часть ущерба уже нанесена.

На самом деле System.Uri - лучший выбор при поддержке схемы навигации на основе URI. Хотя CAB действительно использовал URI-навигацию, он также делал то, что вы сказали, и делал его «похожим» на URI, позволяя вам использовать строки вместо объекта System.Uri. Имена хостов никогда не требовались.

То, что вы просите, - это очень свободный API на основе строк, который может принимать любой строковый синтаксис, который вы в него вставляете, что не дает предсказуемых результатов. Для работы схемы навигации на основе URI / строки должны существовать правила.

Произвольный URI также не будет работать в XF. Список недопустимых символов в URL-адресе, которые допустимы в файловой системе, не совсем мал. Это все случаи, когда строка сработала бы, а URI не будет и потребует либо экранирования, либо того, чтобы пользователь выяснил, почему что-то не работает (или не работает?), И переименовать материал, чтобы он был «безопасным для URI».

Вы можете создать свою собственную абстракцию, если хотите более строгих ограничений (или лучшей семантики / синтаксического анализа / проверки?), Но ИМХО, System.Uri приносит много интернет-багажа, который не является бесплатным. Это похоже на то, как Mono / MonoDevelop создает свой собственный FilePath для представления путей, которые обычно представляют собой просто строки.

По крайней мере, кажется, что все URI считаются относительными, что упрощает ситуацию. В CAB мы также использовали абсолютные uris с частями схемы и имени хоста, что было проблематично.

Я бы предпочел что-то вроде ResoucePath , скажем, чем Uri . Но в конце игры, я почти уверен, что дело сделано.

Я не уверен, какое отношение, по вашему мнению, имеет пути к файловой системе ...

Как бы вы использовали URI, чтобы запутать систему? Он проигнорирует схему и имя хоста и начнет поиск маршрутов (которые ограничены только [az]). Если какие-либо странные символы, которые вы вводите, не могут быть найдены, он просто останавливается. И строка запроса, которую вы вводите, должна быть действительными идентификаторами C #, иначе она просто не будет сопоставлена. Экранированные данные в данных строки запроса не будут экранированы.

@kzu URI отлично работает в XF и лучше подходит для XF, чем схема файловой системы. Фактически, при запуске вашего приложения с веб-сайта ожидается URI. Вы должны проверить, насколько мощной может быть навигация на основе URI, посмотрев на реализацию Prism. Из всех приложений, созданных с помощью Prism, использующих схему навигации на основе URI, никогда не возникало проблем, связанных с недопустимыми символами. Я уверен, что ваши опасения по поводу схемы на основе URI для платформы XF не будут проблемой.

Имеет смысл. Спасибо за справочную информацию о Prism @brianlagunas! Теперь мне следует внимательно прочитать спецификацию и дать несколько действительно полезных отзывов;)

Очень хорошая инициатива, но я надеюсь, что возможности расширения и настройки будут приняты во внимание путем создания соответствующих виртуальных методов или других способов сделать нашу «особенную» вещь для наших клиентов.

Например, можно ли / как:

  1. Расширяемость вкладок, например, отображение значка со значком. Или отображение всплывающего окна над ним, например кнопки «еще» или « * ».
  2. Пользовательская панель закусок (например, с кнопкой «Отменить» для действия, которое вы только что выполнили с пользовательскими цветами фона / переднего плана)
  3. Отправка фрагментов в Android с использованием анимации, отличной от запрограммированной по умолчанию в оболочке, например, без анимации, чтобы обеспечить максимально быструю навигацию.

Техническое примечание: будет ли оболочка перезагружать страницы так, чтобы при двойном переходе на страницу собственные элементы повторно использовались с другой виртуальной машиной под ним?

Привет @rogihee

Жду ваших отзывов о реализации. Я думаю, что это безумно расширяемое: https://github.com/xamarin/Xamarin.Forms/blob/9558f2837280e02b41848d3a3c3213d49a664751/Xamarin.Forms.Platform.iOS/Renderers/ShellRenderer.cs

Android все еще находится в стадии интенсивной разработки, но использует идентичный подход.

@rogihee Что касается

Хорошо смотрятся эти параметры «Создать *». Приятно видеть стремительный прогресс в этом вопросе!

Интересно, есть ли какие-либо последствия для производительности при повторном использовании элементов. Лично я бы отдал приоритет скорости и «плавности» приложения по сравнению с более высоким использованием памяти / ЦП (хотя, конечно, есть корреляция где-то в конце). И отдавайте предпочтение iOS / Android над всем остальным :-).

Shell очень ориентирована на восприятие плавности. Его еще нет везде, но он собирается вместе.

Мне действительно нужно привлечь некоторых первых пользователей, которые пытаются делать сумасшедшие вещи с оболочкой, чтобы убедиться, что она справится с нагрузкой, для которой предназначена.

@jassmith mig только что упомянул оболочку на 3 минуты в сборке .....

Я не его папа

+1

Обновлен API в соответствии с текущим состоянием мира, по-прежнему необходимо обновить образцы.

Добавлены некоторые обновленные образцы, все еще необходимо проделать большую работу по исправлению других образцов и обновлению описаний маршрутов при использовании сокращенного синтаксиса (поскольку вы получаете сокращенные маршруты!)

Черт возьми, я так поздно на вечеринку. Отличная запись и обсуждение. Я просмотрел все это (извините в аэропорту) и у меня есть собственное предложение. Извините, если это было упомянуто где-то еще.

@jassmith @migueldeicaza Не могли бы вы добавить поведение на панель навигации, чтобы его можно было прокручивать при прокрутке ListView и отображать при прокрутке в противоположном направлении. Практически любое профессиональное приложение делает это, чтобы показать больше недвижимости. Это было бы особенно полезно на небольших устройствах.

Другой вопрос: почему бы вам не переименовать теги XAML, чтобы их было проще понять? Может быть, использовать Tab вместо ShellSection? Сейчас много тегов ShellX.

Я считаю, что для iOS есть свойство для включения / выключения, чтобы включить режим прокрутки на панели навигации. Для Android нужно начать использовать новые макеты (CoordinatorLayout, AppBarLayout и т. Д.). Реализация XF для Android в этом отношении довольно устарела, поскольку она все еще использует RelativeLayout в качестве основного контейнера. Я думаю, что где-то есть билет улучшения по этой конкретной проблеме. Я бы хотел, чтобы Shell поддерживала разные режимы прокрутки.

Кроме того, нам часто приходится реализовывать собственное поведение для отображения ошибок / других типов всплывающих окон на странице. Shell должна поддерживать эту функцию из коробки, поэтому нам не нужно прибегать к сторонним плагинам или создавать сложную иерархию пользовательского интерфейса.

@ adrianknight89

Не могли бы вы добавить поведение к панели навигации, чтобы ее можно было прокручивать при прокрутке ListView и отображать при прокрутке в противоположном направлении. Практически любое профессиональное приложение делает это, чтобы показать больше недвижимости. Это было бы особенно полезно на небольших устройствах.

Я действительно пытаюсь придумать правильный способ сделать это. К сожалению, не все платформы поддерживают эту функцию, поэтому, вероятно, это будет сделка для конкретной платформы. Android, по крайней мере, был построен для поддержки этого, я время от времени включаю его, чтобы убедиться, что он все еще работает.

Другой вопрос: почему бы вам не переименовать теги XAML, чтобы их было проще понять? Может быть, использовать Tab вместо ShellSection? Сейчас много тегов ShellX.

Именование здесь ДЕЙСТВИТЕЛЬНО сложно. ShellTab немного сбивает с толку верх и низ. Вместо этого я выбрал более общие иерархические имена, однако должен признать, что меня не устраивает именование. Предложения приветствуются на 100% ... не очень-то с нетерпением жду возможности РЕФакторинга их имен СНОВА, но что я могу сделать ...

Я считаю, что для iOS есть свойство для включения / выключения, чтобы включить режим прокрутки на панели навигации. Для Android нужно начать использовать новые макеты (CoordinatorLayout, AppBarLayout и т. Д.). Реализация XF для Android в этом отношении довольно устарела, поскольку она все еще использует RelativeLayout в качестве основного контейнера. Я думаю, что где-то есть билет улучшения по этой конкретной проблеме. Я бы хотел, чтобы Shell поддерживала разные режимы прокрутки.

Shell использует CoordinatorLayout + AppBarLayout и на данный момент "отключает" поддержку прокрутки, но она работает. Отключение прокрутки iOS также легко реализовать. К сожалению, NavigationView в UWP не поддерживает эту функцию.

Кроме того, нам часто приходится реализовывать собственное поведение для отображения ошибок / других типов всплывающих окон на странице. Shell должна поддерживать эту функцию из коробки, поэтому нам не нужно прибегать к сторонним плагинам или создавать сложную иерархию пользовательского интерфейса.

Примеры, мне нужны примеры :)

@jassmith

Я использую подключаемый модуль Джеймса Монтемагно для прослушивания изменений в состоянии подключения к данным. При обрыве подключения к Интернету рекомендуется отображать скользящее / плавное появление и исчезновение уведомления, которое остается неизменным до тех пор, пока Интернет не вернется в оперативный режим.

В Instagram это уведомление размещается прямо под панелью навигации. В Tumblr это прямо над нижней панелью навигации. На YouTube, как ни странно, он находится под нижней панелью навигации. Может, что-то подобное может быть частью Shell?

Предлагаемый элемент управления Popup, насколько мне известно, перекрывает существующее окно, хотя его можно легко отклонить. Уведомление, которое я только что упомянул, и потенциально другие типы уведомлений не должны перекрывать их родительское окно (т.е. родительское визуальное дерево по-прежнему реагирует на жесты), поэтому я не уверен, что Popup подходит.

Оболочка может иметь свойство для определения того, как будет выглядеть это представление (назовем его Уведомление [View]), а также его размещение и поведение анимации входа / выхода. По сути, кроссплатформенная реализация тостов / закусок, встроенная в Shell, INavigation или что-то еще. Это не будет вынуждено выглядеть нативно для каждой платформы, но будет одинаковым для всех.

d1c014c0-fc7b-4788-9689-1948a7294426

bc91d3ca-b95f-4485-a917-db6ab47510c1

Что касается аргументов в пользу стабильности, гибкости и т. Д., Не избавляясь от устаревшей архитектуры начиная с версии 1.0, я не думаю, что это осуществимо для достижения этих целей. Я очень сторонник ListView2.

@jassmith

  • У вас уже есть билет на усовершенствование нового ListView?
  • Как вы думаете, когда выйдет версия 1.0? Есть ли шанс, что мы сможем увидеть это EOY?

Также меня беспокоит то, что команда слишком мала. Фактически, я уже поднимал этот вопрос раньше. Я надеюсь, что в будущем команда станет намного больше. 🙏 @davidortinau @migueldeicaza

@jassmith Некоторое время я полагал, что если бы у нас был Renderer для класса App, мы могли бы сделать многое, для чего в настоящее время требуется стороннее хакерство. Например, плагин RgPopups захватывает основное представление приложения и вставляет в него визуализированные представления, чтобы обеспечить вид всплывающего окна на весь экран. В настоящее время этого невозможно достичь с помощью «чистых» форм Xamarin. Однако, если бы у приложения был рендерер, мы могли бы сделать это сами.

Я полностью за добавление таких всплывающих уведомлений в Shell, просто пытаюсь понять, как это должно быть сделано.

Не могли бы вы сделать так, чтобы вы могли размещать страницы произвольно в любом месте приложения? Это особенно важно на планшетах / настольных компьютерах / ноутбуках (устройства с большим экраном), где вы хотите, чтобы на экране одновременно отображалось несколько страниц, и не обязательно организовывать их с помощью разделенного представления (главная страница сведений). Пример, см. Карты Google:

image

Обратите внимание, как содержимое «плавает» поверх карты (без разделения). Если вы хотите использовать такие вещи, как вкладки или навигация внутри плавающей области, тогда вы не можете выполнить такого рода вещи с помощью Xamarin Forms из коробки из-за чрезвычайно ограниченной иерархии со страницами (невозможно вложить страницу внутри вида). На самом деле мы разработали собственное настраиваемое представление, которое предоставляет возможности, аналогичные NavigationPage, но является представлением, чтобы мы могли реализовать такой вид макета, но это было много работы / усилий.

Должна быть возможность размещать контент (включая страницы) в любом месте приложения.

Не могли бы вы сделать так, чтобы вы могли размещать страницы произвольно в любом месте приложения?

Мне немного любопытно @jsiemens, так как этот вид, скорее всего, не будет выглядеть правильно на телефоне, но отлично смотрится на рабочем столе и планшете. Не могли бы вы подробнее рассказать о том, как, по вашему мнению, это сработает. В конце концов, я бы хотел сказать, что вы переносите концепцию региона в формы из Wpf. Моя реакция коленного рефлекса заключается в том, что, хотя мне нравится эта концепция, мы рискуем сделать и без того сложный API навигации, требующий докторской степени или, по крайней мере, IQ уровня гения, что не будет лучшим выбором для пользователей.

@dansiegel По крайней мере, лично я, вероятно, использовал бы VSM или какой-либо эквивалент для перемещения и сжатия прокрутки внизу, когда он ниже определенного порога области просмотра (как в настоящее время GMaps). Было бы любопытно увидеть, как для этого будут работать навигация и управление состоянием.

Навигация: я уверен, что это не является непреодолимой проблемой, если вы начали с точки зрения пользовательского пути, а затем посмотрели, как пользователь ожидает, что это будет работать. Навигация должна реагировать на полноэкранный характер телефона, например, на меньший вид на большом экране.

Пользователь будет «видеть» планшет и уменьшенное изображение как единую веху навигации. На маленьком экране могло быть две вехи. Каким-то образом навигация должна быть отзывчивой.

Как разработчики, мы, безусловно, должны иметь дело с этой отзывчивой природой, поскольку это контекстная вещь. Мы не можем полагаться на фреймворк, чтобы справиться с этим за нас, но фреймворк должен это поддерживать.

@jsiemens @dansiegel В настоящее время я использую ControlTemplate s. Я создаю свой контент типа «страница» как ContentView s и размещаю его в ContentPage (внутри NavigationPage ), который соответствует платформе. Использование ControlTemplates означает, что у меня может быть несколько привязанных ContentViews (обычно в Grid чтобы я мог наложить материал), которые включаются / выключаются на основе связываемых свойств в ControlTemplate Сам DynamicResource s). Конечный результат немного похож на панели CSS на веб-сайте, где весь контент находится на странице, но не все его видно все время. ControlTemplate s волшебны для этого, и я бы хотел, чтобы их возможности сохранились в Shell.

@dansiegel Я бы просто закодировал его для загрузки другой оболочки в зависимости от того,

@jsiemens , все в порядке, мой комментарий предназначен только для стимулирования дальнейшего разговора и критического мышления для дальнейшего уточнения вашей идеи. В некотором смысле, учитывая вашу концепцию, я бы почти сказал, что каждая страница может быть по существу MultiPage, где страница может быть прикреплена к данному элементу управления и рассматриваться больше как просто другое представление по сравнению с обычной навигацией.

@dansiegel Да, я думаю, что мне нужно просто добавить страницу в любое место приложения. Странно, что Xamarin Forms накладывает это ограничение, когда базовые платформы этого не делают (например, iOS - это просто древовидная иерархия представлений - вы можете добавить представление NavigationController буквально в любом месте приложения). Кроме того, мой комментарий был предназначен для того, чтобы указать, что спецификация Shell не обязана покрывать это - я не думаю, что «отзывчивый» макет должен вызывать беспокойство. Я думаю, что до тех пор, пока можно построить макет, мы можем позаботиться об условной загрузке оболочек в зависимости от форм-фактора, и этого достаточно.

Я полагаю, что это не совсем по теме данной спецификации, но я упомянул об этом здесь, потому что мы говорим о том, как создавать сложные макеты (например, третий приоритет @MelbourneDeveloper - гибкость), и это, безусловно, макет, который является вершиной помните для меня и моей команды (мы создаем картографическое приложение, в котором мы хотим иметь возможность размещать панели контента поверх карты, которые могут содержать контент только для страницы, такой как страницы навигации и вкладки).

Я не знаю, как это можно решить с помощью оболочки, но моя первоначальная реакция на оболочку такова, что она, похоже, не делает того, чего я уже не могу. Обычно мне кажется, что команда Xamarin Forms продолжает создавать функции, которые позволяют мне делать то, что я уже мог делать, но только другим способом (например, CSS, Visual State Manager, а теперь и спецификации Drawing и Shell). Так что для меня это не имеет большого значения. Я бы предпочел иметь новые функции, которые позволят мне делать то, что я раньше не мог (за пределами настраиваемых элементов управления и / или средств визуализации). Если оболочка - это ответ для достижения этого, потому что синтаксис более элегантен, тогда я полностью за это, но в конечном итоге я хотел бы, чтобы он был более мощным и выразительным, чем текущая иерархия страниц / представлений, поскольку это действительно приносит пользу.

Не могли бы вы отделиться от создания собственного представления для каждого представления xamarin, если все подпредставления в макете можно визуализировать без использования собственных виджетов? Вид автоматического гибридного подхода flutter / xamarin, при котором группы представлений XF отображаются на одной поверхности и просто переносятся на одно собственное представление. Было бы полезно избежать создания / макета представления Android c # -> java interop cost.

в ходе выполнения!!

@jassmith после того, как оболочка закончила, будет ли работать вместе?

будет ли оболочка поддерживать macos и wpf?

@juepiezhongren начальные цели - iOS и Android. После этого приоритет будет отдан другим платформам.

Рисунок в настоящее время не разрабатывается. В текущей спецификации это было бы применимо к Shell. Как и сегодня, вы можете использовать элементы управления на основе SkiaSharp и Skia в Xamarin.Forms.

Мы работаем над другими собственными стратегиями для поддержки согласованного дизайна материалов и других стилей дизайна.

@davidortinau Улучшает ли оболочка поддержку RTL?

Лучше чем? Чего вам не хватает сегодня в поддержке RTL? Мы должны решать это везде.

Честно говоря, я давно не занимался разработкой XF, но большинство ограничений известно: взгляните на # 1222 и # 2448.

Возможно, оболочка может помочь с этими общими ограничениями:

  • Расположение кнопки NavigationPage, расположение элемента панели инструментов и анимация перехода в настоящее время контролируются языковым стандартом устройства, а не настройкой FlowDirection.
  • Глобальная настройка приложения для FlowDirection

И некоторые другие ограничения, специфичные для платформы

Самая важная особенность Xamarin.Forms. Во-первых, он должен был быть построен таким образом.

без рисования, xf еще очень много не хватает

@juepiezhongren

Просто используйте Skiasharp

@mackayn я много использовал это
https://github.com/xamarin/Xamarin.Forms/issues/1789
универсальный вид - необходимость

адам начал трепетать, это действительно печальный знак для xf, где xamarin изначально мог довольно легко добиться гораздо лучшей репутации

xamarin.native намного более надежен для xf, чем любые другие кроссплатформенные решения, независимо от того, как реагируют нативные или нестабильные. Как любитель дотнетов, текущая ситуация с xf всегда немного разочаровывала меня.

@juepiezhongren

Это обсуждение бессмысленно, если оно не соответствует вашим потребностям, используйте Flutter, оно позволяет нам доставлять приложения на нескольких платформах (iOS и Android только с Flutter и т. Д.), Эти изменения сделают согласованный вид и более достижимыми.

простые мелкие жалобы, просто так много. По-прежнему ура для снаряда!

Я согласен, что было бы лучше, если бы Skia намного больше запекалась в API форм (как это сделал Telerik). Я согласен.

Я рад, что они вкладывают усилия в Shell и CollectionView.

Привет, пожалуйста, все скажите, как я могу использовать флайаут на правом и левом языках.

Привет,

Мне нравится эта идея, но у меня есть лишь несколько небольших предложений.
Думаю, я немного опоздал, но, думаю, название немного сбивает с толку.

  1. Item, Section и Content - это действительно общие названия. Не сразу понятно, в каком отношении они находятся. Это Content => Section => Item или Section => Content => Item, или Item => Section => Content.
    Таким образом, мы могли бы указать немного больше, что представляют собой различные «вещи», найдя более конкретное имя.

  2. Это подводит меня к следующему выводу. У нас есть Shell как контейнер для всех внутренних предметов. Так что нельзя просто использовать прямые имена, такие как «Item» вместо «ShellItem» внутри. Мне кажется немного ненужным называть все "вещи" Shelltem, ShellSection и т. Д., Но все в порядке. это спорно.

Ой

Будет ли он выпущен в 2018 году?

У нас есть предварительный выпуск СЕЙЧАС! Взгляните на https://blog.xamarin.com/connect-2018-xamarin-announcements/, чтобы найти отличные образцы.

Нам действительно нужен Android 9? Это может показаться ограничением.

Все это звучит неплохо, но, похоже, основано исключительно на взаимодействии с пользовательским интерфейсом.
Думаю, я узнаю, когда попробую, но моя первоначальная проблема заключается в том, как управлять навигацией из бизнес-логики или кода, например, сообщений, полученных от подключенного через Bluetooth устройства, инициирующего смену страницы, сохраняя при этом достойное разделение проблем?

@hassanrahimi

Привет, пожалуйста, все скажите, как я могу использовать флайаут на правом и левом языках.

Хотя RTL поддерживается, всплывающее меню по-прежнему отображается слева. Это текущее ограничение.

Можно ли настроить пользовательский интерфейс нижней панели вкладок?

Можно ли добавить в оболочку элементы управления, которые не перезагружаются при навигации внутри оболочки? Например FAB ..

Пользовательский интерфейс нижней панели

Добавление элементов управления, которые являются глобальными, как вы описываете как FAB, планируется для MaterialShell. Можете ли вы предоставить дополнительные сценарии, которые выиграют от этого в дополнение к FAB?

Во-первых: раньше я использовал свою собственную оболочку, теперь я могу довольно легко заменить свою собственную оболочку на вашу, и это намного лучше. Мне это и вправду нравится.

Вероятно, мои случаи являются индивидуальными и не связаны с оболочкой, но:

Случай первый:
Если я хочу создать приложение с очень индивидуальным меню, по одной кнопке меню в каждом углу приложения, как мне добавить кнопки, чтобы они стали частью оболочки (например, наложение или рекламный щит). Не хочу, чтобы он перерисовывался каждый раз, когда я перемещаюсь.

Случай второй:
Я хочу использовать оболочку, но хочу настроить нижнюю панель вкладок так, чтобы средняя кнопка была выше (так называемая центральная приподнятая кнопка). Следует ли мне использовать средство визуализации и настраивать вид нижней навигации?

Как вы думаете, мне следует использовать оболочку для таких особых случаев?

Конечно, я думаю сделать это на каждой платформе, но меню должны выглядеть одинаково на всех платформах, поэтому хочу поделиться кодом.

Вот мой отзыв. Я провожу этот тест ( 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>

Все работает, когда мы нажимаем на гамбургер-меню. Однако, если мы перейдем в меню Test и нажмем Home и Notifications назад и вперед и выберем между Recent или Settings , страница откроется соответственно. Но затем, когда мы снова нажимаем на гамбургер-меню, приложение вылетает.

image

Как мы можем использовать GroupHeaderTemplate для отображения заголовка группы ShellContent в ShellItem?

Многим пользователям ясно, что Xamarin Forms не поддерживает текущий размер и сложность, поэтому все новое должно уменьшать сложность, а не увеличивать ее.

@jassmith Намерение состоит в том, что вам НИКОГДА не лучше

Если Shell будет завершена, что в будущем может быть обесценено, и когда это будет сделано, уменьшится ли общая сложность Xamarin Forms? Будут ли обесценены все остальные страницы, кроме ContentPage?

Стратегия должна заключаться в том, чтобы получить от репо как можно больше. Стабильность и ремонтопригодность основного репо - это самое главное.

Также, есть ли причина, по которой Shell не называется ShellPage? Имена других классов страниц заканчиваются на «Page».

Текущая реклама Shell (в https://blog.xamarin.com/xamarin-forms-4-0-preview/) не является многообещающей.

  1. Упрощенный способ выразить высокий уровень архитектуры вашего приложения

Это выводит Xamarin за рамки его реальной цели. Xamarin не нужен для архитектуры приложений. Это должно касаться только макета.

  1. Иерархия общих шаблонов навигации пользовательского интерфейса, подходящих для ваших целевых мобильных платформ.

Я надеюсь, что слово «мобильный» - это опечатка, потому что Xamarin.Forms охватывает и рабочие столы.

  1. Надежный навигационный сервис

Xamarin.Forms не требует навигации. Если текущая навигация не работает, ее можно просто обесценить, потому что есть много хороших подходов к навигации, которые не требуют ничего встроенного.

Привет, @charlesroddie , спасибо за отзыв.

Похоже, Shell в настоящее время вам не подходит, и это нормально. Вам не нужно использовать Shell, если он не приносит пользы вашим приложениям. Тем не менее, спецификация Shell в значительной степени основана на отзывах разработчиков, и обслуживание нашего сообщества разработчиков является ключевым моментом для нашей цели.

Сегодня в Xamarin.Forms вы уже описываете архитектуру своего приложения, иерархию контента, используя TabbedPage, MasterDetailPage, вкладки и пункты меню, а также различные комбинации. Вот что я имею в виду под «архитектурой». Shell упрощает и заменяет эти шаблоны (если вы решите использовать Shell).

«Мобильный» - это не опечатка, и оно используется очень сознательно. Shell нацелена на iOS и Android. Если вы нацеливаетесь на рабочий стол, вы не будете использовать Shell. Я слышал интерес со стороны участников о добавлении поддержки Shell в серверные части рабочего стола, и эти PR будут хорошо приняты. Я считаю, что Shell очень хорошо позиционирует себя, чтобы переносить приложения на любую платформу и быть гибкой (устойчивой), чтобы адаптироваться даже к радикальным изменениям паттернов пользовательского интерфейса (кто знает, какие интерфейсы будут приняты в будущем). На сегодняшний день полигон - iOS и Android.

Когда мы говорили с разработчиками о Shell, я был удивлен, узнав, что навигация Shell была в верхней части списка функций, которые они ценили. Маршрутизация, глубокие ссылки, возможность прерывания навигации, мгновенное описание обратного стека, передача данных и отложенная загрузка страниц - очень важные атрибуты для разработчиков, которые решают проблемы, с которыми они сталкиваются сегодня.

Если вы нацеливаетесь на рабочий стол, вы не будете использовать Shell ... Я считаю, что Shell очень хорошо позиционируется, чтобы переносить приложения на любую платформу

Я просто не хочу, чтобы Xamarin рухнул под собственной тяжестью. Пока Shell не достигнет всех платформ, у вас возникнут проблемы с обслуживанием, поскольку тогда это дополнение, а не замена других страниц. У вас также есть проблема с обменом сообщениями для разработчиков настольных компьютеров в то время, когда многие явно стремятся принять кроссплатформенную структуру.

Xamarin демонстрирует множество нестандартных функций, например css. Это может поставить под угрозу весь проект, и я надеюсь, что некоторые лица, принимающие решения в организации, это понимают.

Я просто не хочу, чтобы Xamarin рухнул под собственной тяжестью. Пока Shell не достигнет всех платформ, у вас возникнут проблемы с обслуживанием, поскольку тогда это дополнение, а не замена других страниц. У вас также есть проблема с обменом сообщениями для разработчиков настольных компьютеров в то время, когда многие явно стремятся принять кроссплатформенную структуру.

Xamarin демонстрирует множество нестандартных функций, например css. Это может поставить под угрозу весь проект, и я надеюсь, что некоторые лица, принимающие решения в организации, это понимают.

Я согласен. Если функция не поддерживается на настольных компьютерах (UWP), тогда она нам бесполезна. Я также согласен с CSS - кажется, что это создает дополнительную сложность и накладные расходы на обслуживание функции, которая не позволяет мне делать то, что я не мог сделать раньше. Нам больше всего нужно больше элементов управления - для всех платформ и больше возможностей для существующих элементов управления. Shell по-прежнему имеет те же ограничения, что и инфраструктура Page, поскольку вам необходимо полностью принять ее или вы не можете ее использовать вообще, и она может существовать только на корневом уровне вашего приложения. Более того, теперь у вас есть два способа сделать одно и то же, и это сложно и запутанно. Поэтому, если я хочу иметь всплывающее меню без использования оболочки, я не могу этого сделать. И он чрезвычайно ограничен в количестве элементов управления, которым сопоставляются элементы оболочки - вкладок, страниц навигации и всплывающих окон для нас недостаточно. Если бы Xamarin Forms мог предложить широкий спектр элементов управления, которые есть в такой платформе, как UWP, представленных в виде набора элементов управления, как в UWP, и без бесполезного раздувания (например, css), то я был бы счастлив.

Я думаю, что вы, ребята, поднимаете некоторые веские вопросы, но как человек, поддерживающий приложение UWP / iOS / Android, был немного разочарован, когда я узнал, что Shell не поддерживает UWP, только «может быть» в будущем. Потом я понял, что упускаю суть Shell. Это отличный простой способ создать приложение для двух основных мобильных платформ. Как корпоративный разработчик ... Мне нужен UWP, я ждал, пока появится поддержка UWP, чтобы даже рассмотреть XF ... но я подозреваю, что многим разработчикам он не нужен ... Мне также нужна более сложная навигация и т. Д. Shell предоставляет.

Но я также помню, как потратил много времени, пытаясь начать работу с навигацией и страницами ... что может занять некоторое время, чтобы разобраться. Но я также делаю очень сложное бизнес-приложение, есть множество простых приложений, которым просто не нужен такой уровень сложности. XF должен развиваться, чтобы противостоять таким вещам, как Flutter и т. Д. Он также должен постоянно привлекать новых разработчиков. И мне кажется, что использование платформы поможет обезопасить ресурсы, необходимые для поддержки платформы.

У меня также есть пара будущих проектов, в которых мне не нужна UWP, и я с нетерпением жду возможности использовать в них Shell, потому что я думаю, что это позволит мне гораздо быстрее их создавать.

Я использую XF только с момента выпуска 2.3, и хотя, безусловно, предстоит еще многое сделать ... платформа в том виде, в котором она существует сейчас, значительно стабилизировалась ... по крайней мере, для меня ... так что меня не волнует дополнительное обслуживание и исторически мне кажется, что команда XF очень осознает бремя обслуживания ... так что я верю, что они держат это под контролем.

Спасибо за отличное дополнение к платформе!

Добавление новых способов работы будет сбивать с толку новых разработчиков до тех пор, пока старые способы не станут устаревшими и старые документы не будут удалены.

Flutter намного проще. Нет языка разметки, все в коде. Xamarin не собирается конкурировать, становясь более сложным и ошибочным. Он будет конкурировать, делая больше, чем Flutter (больше платформ), с тем же фокусом.

Дошло до того, что нам нужен Xamarin.Core, не включая XAML, CSS или привязки свойств, не включая страницы или оболочки за пределами базовых классов, с упором на производительность и стабильность этого ядра. Если некоторым разработчикам нужны эти функции за счет принятия текущего количества ошибок, они могут использовать Xamarin.Extensions там, где все эти вещи будут жить.

Добавление новых способов работы будет сбивать с толку новых разработчиков до тех пор, пока старые способы не станут устаревшими и старые документы не будут удалены.

Flutter намного проще. Нет языка разметки, все в коде. Xamarin не собирается конкурировать, становясь более сложным и ошибочным. Он будет конкурировать, делая больше, чем Flutter (больше платформ), с тем же фокусом.

Дошло до того, что нам нужен Xamarin.Core, не включая XAML, CSS или привязки свойств, не включая страницы или оболочки за пределами базовых классов, с упором на производительность и стабильность этого ядра. Если некоторым разработчикам нужны эти функции за счет принятия текущего количества ошибок, они могут использовать Xamarin.Extensions там, где все эти вещи будут жить.

@charlesroddie Ничего из того, что они сделали выше, не заставляет вас использовать XAML. XAML в Xamarin.Forms не является обязательным - так было всегда. Я всегда использую пользовательский интерфейс своих приложений Xamarin.Forms с использованием только кода - каждый «тег», который вы видите выше, является классом, который можно создать и добавить к соответствующему родительскому элементу.
Если бы закодированный пользовательский интерфейс был невозможен с Xamarin.Forms, я бы не стал его использовать - точка!

Re Flutter в целом - это очень хорошо, но проблема только в iOS и Android - это тоже не работает для меня, поскольку мне нужно настроить таргетинг на macOS, Windows 7 / 8.1 и Linux. В этом нет ничего лучше Xamarin.Forms!

Могу ли я установить пользовательское представление в качестве главной страницы, это очень важно включить, мы не предпочтем только MenuItem или страницы

Поддержка Xamarin Mac и uwp?

Как бы вы подключились к процессу навигации? Я думаю, вы знаете об этом, но если вы возьмете Prism, например, модели представления создаются контейнером DI и автоматически устанавливаются как BindingContext для запрошенной страницы.

Вы также можете реализовать INavigatedAware для модели представления и обрабатывать конкретные варианты использования, такие как загрузка данных, включение / отключение служб и т. Д.

Я хотел добавить что-то подобное, поэтому моим первым предположением было событие OnNavigating и OnNavigated Shell, но Current и Target не раскрывают ShellItem, поэтому это невозможно установить BindingContext по соглашению или инициировать события модели представления?

Есть предложения по этому поводу?

РЕДАКТИРОВАТЬ: отслеживается # 5166.

Можно ли использовать для значков в этой оболочке «Шрифт значков» вместо изображения? Сложно изменить цвет во время выполнения для изображения, а также сложно управлять ими для разных разрешений на разных платформах. Могу ли я предложить создать класс значков с использованием шрифта Material Design, созданного с помощью библиотеки SkiaSharp? Класс относительно прост и сделает множество значков готовыми к использованию в оболочке.

@vincentwx Я согласен. Иконочные шрифты намного проще в использовании, и они тоже знакомы.

@vincentwx @stevehurcombe абсолютно. Я делаю это прямо сейчас в приложении:

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

Я использовал это, чтобы создать статический класс всех глифов: https://andreinitescu.github.io/IconFont2Code/

Есть ошибка с цветом iOS, которую нужно исправить. # 5071

Поддержка Xamarin Mac и uwp?

Не сейчас @mdonogma. Мы собираем интерес / спрос на поддержку дополнительных платформ, но в настоящее время это не входит в нашу дорожную карту.

@davidortinau Спасибо за код и ссылку.

В Android 8.0 я не могу прокручивать веб-страницу в элементе WebView который размещен в Shell Content. Но он отлично работает без Xamarin Shell.

Xamarin Form 4.0.0.135214-pre4

Есть ли простой способ изменить FontFamily нижних вкладок и заголовка?

@varyamereon Я сделал это вчера. Extenend the Shell, чтобы иметь возможность установить FontFamily.
Я скоро опубликую свою расширенную оболочку на GitHub, но:

Создайте настраиваемую оболочку:

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

Затем создайте настраиваемое средство визуализации Shell:

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

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

Потом:

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

Затем установить семейство шрифтов: _ (не делайте это слишком часто) _

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

Кто-нибудь, кто расширил Shell поддержкой всплывающего окна снизу (нижний лист)?

Я переместил много кода из моей старой оболочки в новую (конечно, композиция), мне это очень нравится. Я даже использую его для приложения, которое будет выпущено в мае :-) (я отлаживаю даже код Xamarin)

Есть ли поддержка привязки списка к Shell.MenuItems? Или мне следует использовать BindableLayout? Иногда мне нужно загрузить список из базы данных и использовать его как меню. У них одинаковое представление, но загружаются разные данные в зависимости от выбранного меню.

Есть ли способ изменить OffscreenPageLimit в Android при использовании оболочки? К сожалению, это очень важно для моего приложения и мешает мне продвигаться вперед с Shell.

Спасибо!

Пара запросов функций:

  1. На уровне оболочки установите FontFamily для всех заголовков страниц.
    например

  2. На уровне оболочки установите фоновое изображение заголовка / навигации для всех заголовков страниц / панелей навигации и т. Д.
    например

GroupBehavior у меня не работает в pre4:

<ShellItem GroupBehavior="ShowTabs" FlyoutIcon="stuff.png" Title="Discussion">...
приводит к:

xxx / Shell / Shell.xaml (14,14): Ошибка: позиция 108: 14. Для GroupBehavior не найдено свойство, привязываемое свойство или событие или тип несоответствия между значением и свойством.

и GroupHeaderTemplate, похоже, ничего не делает, но не уверен, как он используется или включен.

Я пытаюсь добавить / удалить MenuItems, который успешно добавляет элементы через MenuItems.Add (item), но при повторном отображении всплывающего окна результат не отображается. Это правильный подход?

Я не вижу никакого упоминания о манипулировании элементами меню, но оболочка для меня в значительной степени бесполезна (и я думаю, что многие другие, включая @puppetSpace выше), если эти элементы не могут поддерживаться динамически на основе вашей бизнес-логики.

Я согласен с dbwelch в том, что возможность программного изменения оболочки в файле cs очень важна. Не только для пунктов меню, но и для ShellItems и ShellSections.

Когда я включаю Flyout и добавляю пункты меню, я получаю гамбургер-меню в Android, а в iOS, если я щелкаю в этом месте, оно работает, однако значка нет. Любые идеи?

@KyleTraynor где-то есть открытая проблема. Вам необходимо вручную скопировать изображения 3bar.png и [email protected] в папку ресурсов iOS и убедиться, что они включены в проект как элементы пакета.

Изображения, которые я нашел в источнике, прилагаются:
3bar 2x
3bar

@melucas Спасибо за помощь! Я сходил с ума, пытаясь это исправить. Работает отлично.

Вы случайно не знаете, как я могу установить OffscreenPageLimit для Android при использовании Shell?

У меня есть верхние вкладки, созданные с помощью 4 ShellContents внутри 1 ShellSection, и он отлично работает на iOS, но на Android страницы перезагружаются при переключении между ними, что мне не нужно. Обычно с моей собственной страницей с вкладками я мог бы установить OffscreenPageLimit, чтобы решить эту проблему, но я не могу найти способ сделать это с помощью Shell.

@davidortinau, можно ли установить семейство шрифтов для заголовков страниц, нижних и верхних вкладок? В каждом проекте мне приходится создавать собственные рендеры для iOS и Android, чтобы менять шрифты.

Итак, учитывая, что, поскольку на мое сообщение о возможности фактически изменять элементы во всплывающей оболочке не было никакого ответа, возможно, эта функция не входит в сферу применения, или, возможно, мы надеемся, что она считается ошибкой?

Не уверен, как серьезное приложение может использовать эту оболочку без этой функции. Только очень простые приложения не требуют возможности добавлять / изменять / удалять / отключать элементы в своих меню на основе а) контекста пользователя (т.е. аутентифицированного / не аутентифицированного) или б) различных состояний приложения, которые могут требуется это.

Просто любопытно, @jassmith , люди, создавшие спецификацию, введены в этот форум или это только для отзывов разработчиков?

Кстати, помимо этого одного важного элемента, я внедрил Shell в свой код для одного приложения, и оно работает очень хорошо, спасибо! Но, к сожалению, придется вытащить его и реализовать собственное всплывающее окно, если в оболочке не работает / не реализована эта функция.

@dbwelch , пара вещей.
Вы публикуете информацию о спецификации, поэтому вы, вероятно, не получите ответа, как если бы вы написали, открывая новую проблему. Кроме того, Джейсон больше не работает над Forms, поэтому вызывать его бессмысленно.

Итог, напишите о проблеме

@dbwelch @ChaseFlorell Я открыл здесь проблему: https://github.com/xamarin/Xamarin.Forms/issues/5428

@davidortinau, можно ли установить семейство шрифтов для заголовков страниц, нижних и верхних вкладок? В каждом проекте мне приходится создавать собственные рендеры для iOS и Android, чтобы менять шрифты.

@jamiewest Отправьте запрос функции! Спасибо! 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

Можно ли реализовать функцию UseSwipeGesture?
Похоже, что теперь у класса ShellItem нет свойства ShellAppearance для Opera.
Но теперь в Android вкладки Shell не похожи на TabPage (по умолчанию TabPage может пролистывать).

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

@jingliancui , брат Цуй, есть ли QQ или WeChat?

@juepiezhongren Привет, ты можешь присоединиться к этой группе qq, чтобы поговорить со мной 313308215

Увидим ли мы появление оболочки и визуальной поддержки для UWP после окончательной первоначальной версии?

Я приветствую эту идею - независимо от того, что она усложняет, потому что работа со страницами навигации, страницами с подробными сведениями и т. Д. Кажется запутанной. Может быть, это потому, что я пришел из Интернета (мало работал с собственными API). Здесь на ум приходит настройка панели навигации, заголовков страниц, кнопки «Назад», элементов панели инструментов, верхних и нижних колонтитулов (ListView) и т. Д.

Я полагаю, что я прошу, чтобы новые функции, такие как * Shell, поставлялись с учетом настройки и расширяемости. У нас очень мало ситуаций, в которых нам не нужно было бы создавать серию средств визуализации, поведения, триггеров и т. Д. Для выполнения, казалось бы, простых вещей.

Что бы вы ни придумали, пожалуйста, сделайте все возможное, чтобы нам было проще сделать наши приложения Xamarin.Forms такими же хорошими, как и другие нативные приложения! Похоже, эта функция даст нам лучшую стартовую панель для современных приложений XForms!

Доступен ли исходный код, чтобы увидеть, как работает эта оболочка, вместо того, чтобы гадать о спецификации? Например, в каком стиле раскрашивается значок гамбургера, если он есть. Извините, новинка в C # / Xamarin, но, если бы код был где-то доступен для просмотра, это очень помогло бы.

@dbwelch, вы можете просмотреть исходный код прямо здесь, на GitHub. Нажмите «T» и введите Shell, чтобы увидеть связанные классы. Однако это может быть не лучшей отправной точкой, если вы новичок в C # / Xamarin. Я рекомендую проверить некоторые из моих образцов, пока мы не соберем больше документации:

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

Документы: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell?tabs=android
Статья MSDN: https://msdn.microsoft.com/en-us/magazine/mt848639
Блог: https://blog.xamarin.com/xamarin-forms-4-0-preview/

@davidortinau, спасибо, но я думал, что это только что выпущенный код, который был доступен, где код Shell? Заглянул в ветки на 4.0, Шелл и другие, но это от меня прячется! Спасибо!

@pauldipietro Спасибо, посмотрите сейчас. @davidortinau На самом деле я потратил много времени на все ссылки (кроме LittleThings, который я только что скачал), но просто не понимаю, как изменить такую ​​простую вещь, как цвет значка гамбургера. В моем приложении он отображается как фиолетовый, но у меня нигде не определен фиолетовый цвет (который я могу видеть). Немного расстраивает ;-).

ОБНОВЛЕНИЕ: я только что обнаружил проблему, и, конечно же, в FinishedLaunching есть какой-то неприятный код для добавления TintColor. DOH!

Спасибо господа, ценим помощь!

У меня есть некоторые элементы, отображаемые на всплывающей панели, и это нормально. Однако в настоящее время уже есть способ скрыть / не отображать элемент оболочки (не содержимое элемента). Например, у меня есть ContentPage, и я просто хочу иметь навигацию внутри оболочки.

<local:DetailPage />

Кажется, всегда добавляется элемент в панель / список Flyout. А если заголовка нет, то у него будет пустой стек / заполнитель элемента. Я пробовал много способов спрятать предмет, но безуспешно. Возможно, кто-то может помочь или функция еще недоступна.

Предисловие: Я новичок в банкомате. Пытаюсь не быть.

@davidortinau Итак, я пытался изучить эту функцию Shell, чтобы добавить навигацию и т. д. в наш первый проект Xamarin.Forms для нашей компании (woot!), и я застрял в попытке выяснить, можно ли передать 1 или несколько параметров из ShellItem в другие части приложения с помощью новой функции маршрутизации. Это вообще что-то? Или мы должны придерживаться команд, используя вместо этого MenuItems в коллекции MenuItem? Если мы должны использовать MenuItem для передачи 1 или более значений с уровня Flyout, может показаться, что мы больше не можем структурировать наше приложение с помощью иерархии Shell, поскольку вместо этого мы используем MenuItems? Разве мы не теряем это при использовании MenuItems с параметрами команд?

Есть ли кто-нибудь, кто может вмешаться в это? Если так, я был бы очень признателен. В принципе, хотелось бы использовать Shell, но все же иметь возможность пометить, какой ShellItem пользователь выбрал, щелкнув один, чтобы передать его на страницу ContentTemplate или что-то подходящее, поскольку многие ShellItems будут переходить на аналогичную промежуточную страницу для создания OrderType и сначала выберите раскрывающийся список OrderDepartment, прежде чем перейти к основному экрану Order с соответствующими данными для нужного типа и отдела.

Также прошу прощения, если это не место для этого. Если да, то укажите мне правильное место. Спасибо!

Обновлять:
Возможно, я сейчас просто воспользуюсь MenuItems и передам параметр команды в ShellViewModel для навигации с правильными значениями для целевой страницы. Теперь, когда я думаю об этом, мне действительно не нужно переходить к структуре с вкладками из тех элементов MenuItem, которые отправляются на страницу ContentTemplate.

Мне также было интересно, можем ли мы определить, где расположены элементы MenuItem во всплывающем элементе, чтобы все элементы ShellItem не появлялись наверху; и если однажды нам не нужно будет определять наши MenuItems как часть коллекции, чтобы они могли смешиваться с ShellItems, например:
MenuItem
ShellItem
ShellItem
MenuItem
ShellItem
MenuItem
...
Или просто сделайте ShellItems способным передавать параметры в какой-то момент, если они еще не могут.

Я работаю с @anthcool и считаю это чрезвычайно важной функцией. Я не смог найти способ сделать это, и мне пришлось прекратить использовать Shell. Просто нужно иметь возможность передать что-то на страницу с контентом, чтобы знать, на что было выполнено нажатие.

@anthcool просто пытается помочь и дать какое-то предложение, как то, что я делал в данный момент. Создайте класс параметров навигации, который имеет readonly Stack<NavigationParameter> в качестве списка стека, т.е.

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

Параметр NavigationParameter:

public class NavigationParameter : NameValueCollection { }

Вы можете добавить параметры перед нажатием при навигации, например:

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

Как только вы перейдете на другую страницу, просто взгляните или выберите значение и проверьте ключ.
Что-то вроде выше. Надеюсь, это поможет.

@anthcool просто пытается помочь и дать какое-то предложение, как то, что я делал в данный момент. Создайте класс параметров навигации, который имеет readonly Stack<NavigationParameter> в качестве списка стека, т.е.

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

Параметр NavigationParameter:

public class NavigationParameter : NameValueCollection { }

Вы можете добавить параметры перед нажатием при навигации, например:

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

Как только вы перейдете на другую страницу, просто взгляните или выберите значение и проверьте ключ.
Что-то вроде выше. Надеюсь, это поможет.

Спасибо за идею @rizamarhaban! Очень признателен, что вы участвуете в этом. Спасибо! Я скоро проверю это здесь. Опять же, ценю!

Очень разочарован, узнав, что Shell и Visual не поддерживают UWP.

Это действительно сделано?
Зачем закрывать это только потому, что теперь есть реализация Tizen?
У меня создалось впечатление, что функциональность навигации все еще находится на рассмотрении.

По-прежнему нет поддержки UWP. Самое большое разочарование в Xamarin.

@weitzhandler Напишите мне, пожалуйста, на пол. [email protected], если вы хотите обсудить это и UWP в целом. Мы активно не игнорируем платформу, но Android и iOS получают начальную реализацию, и исследования поддержки Shell для UWP активно продолжаются.

@mrlacey Нет, это еще далеко не готово! Он просто закрывается из-за связанных проблем. 😄

Для всех, кто просил о поддержке UWP, я попытался нанести удар: https://github.com/xamarin/Xamarin.Forms/pull/6015

Есть ли способ реализовать шаблон панели навигации на странице содержимого?
Указание NavigationPage.TitleView не применяется, как раньше.
Репо для справки:
https://github.com/InquisitorJax/Xamarin-Forms-Shell

РЕДАКТИРОВАТЬ:
Мерфи снова наносит удар - просто используйте Shell.TitleView вместо NavigationPage.TitleView :)

Привет,
В моем новом проекте я использую Shell и CollectionView, и я должен сказать, что они великолепны!
Один вопрос о Shell

  • есть способ добавить фиксированный нижний элемент (например, кнопка для выхода пользователя из системы)

Я вижу, что можно добавить фиксированный заголовок (FlyoutHeader и FlyoutHeaderBehavior), но я не могу найти никакой информации о нижнем колонтитуле
Спасибо!

Привет,
У меня еще вопрос по RegisterRoute.
У меня приложение довольно большое, с немалым количеством страниц, около 30 ...
Действительно ли правильный способ добавить RegisterRoute для каждого из них?
Routing.RegisterRoute("blabla", typeof(BlaBlaPage)); ... ...
Или лучше по старинке?
var blaPage = new BlaBlaPage (); await Navigation.PushAsync (blaPage);

@matteopiccioni Я бы порекомендовал сделать это вот так

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

и используя
gotoasync("blabla")

Сейчас я понимаю, что чувствую то же самое, но по мере роста функций будет более актуальным, чтобы все эти вещи работали через систему Shell.

Действительно ли правильный способ добавить RegisterRoute для каждого из них?

если это станет проблемой, мы планируем добавить некоторые функции, которые будут просто сканировать сборку в поисках страниц, или, возможно, даже некоторые функции времени компиляции, которые будут генерировать эти маршруты.

Основная проблема здесь в том, что любой тип отражения замедлит ваше приложение, поэтому выполнение этого при запуске будет стоить

@PureWeen спасибо за ответ
Медленное время запуска - одна из самых неприятных проблем в xf (для Android)
Могу ли я при запуске добавить в маршрутизацию только первый уровень страниц (страницы shellitems) и добавить остальные только после запуска приложения (своего рода ленивая загрузка RegisterRoute)?

@matteopiccioni

Итак, если вы просто сделаете это так все сразу

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

все нормально. Все, о чем я говорил, это то, что если мы в конечном итоге создадим что-то, что позволит пользователям не делать этого, нам нужно будет взвесить это с производительностью. Прямо сейчас Routing.RegisterRoute("blabla", typeof(BlaBlaPage)); не выполняет никаких отражений, так что делать все сразу можно.

все, что он делает, это добавляет строку и тип в словарь

@jassmith @jamesmontemagno @pierceboggan Вау отлично выглядит. Вы видели приложение Google Контакты, использующее Pie SDK на Google Pixel? Мне нравится UI / UX, без заголовка и гамбургера, интегрированного в верхнюю часть приложения.

Можно ли рассмотреть это предложение для вашей оболочки, поскольку это шаблон, который использует Google, с контактами и картами, и, возможно, с другими?

Спасибо за ваше время и внимание,

Карл

Обратите внимание, что во всех следующих примерах не используются шаблонные ShellContent, которые обсуждаются в другом месте спецификации. Неправильное использование ShellContents с ContentTemplate приведет к загрузке всех страниц при запуске, что отрицательно скажется на производительности запуска. Эти образцы предназначены только для обучающих целей.
К счастью, использование ShellContents с ContentTemplates обычно более лаконично, чем их неиспользование.
[...]
Основная проблема с использованием Shell - это легкость, с которой пользователь может в конечном итоге загрузить все страницы в начале запуска своего приложения. Это большое выделение с предварительной загрузкой может привести к довольно низкой производительности при запуске, если требуется большое количество страниц с содержимым. Для исправления этого шаблона следует по возможности использовать.

Для меня это звучит так, как будто вы никогда не должны использовать контент напрямую, а использовать шаблоны. Для меня это имеет смысл, так зачем поддерживать прямой контентный подход? (кроме простоты, но это позволяет людям прострелить себе ногу). Похоже, что возможность использовать прямой контент - это скорее «отличная функция для демонстрации - в противном случае - ужасная» функция.

Привет,
Я новенький здесь. Я не уверен, что это подходящее место, чтобы задавать вопросы, в противном случае, пожалуйста, укажите мне, где спросить:
Я попытался сделать что-то похожее на пример, указанный выше:

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

Но у меня были следующие ошибки:

Ошибка XLS0413 Свойство ItemsSource не найдено в типе ShellItem.
Ошибка XLS0415 Присоединяемое свойство ItemTemplate не найдено в типе ShellItem.

@PureWeen Я надеялся использовать эту идею :).
Вы предполагаете, что эта идея еще не реализована?
Если он еще не реализован, мне может быть интересно поработать над ним.

Это не реализовано, если бы это было!

отправлено из моего Айфона

5 мая 2019 года в 11:59 Элаши < [email protected] [email protected] > написал:

@PureWeen https://nam05.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FPureWeen&data=02%7C01%7C%7C5a4c31a04c6541d6080608d6d172b36a%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C636926687892526088&sdata=Y3%2Fxx % 2BGt13FFjR5BCwdMg0UouarnTxI0% 2FawrXtVEURM% 3D & reserved = 0 Я надеялся использовать эту идею :).
Вы предполагаете, что эта идея еще не реализована?
Если он еще не реализован, мне может быть интересно поработать над ним.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub https://nam05.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fxamarin%2FXamarin.Forms%2Fissues%2F2415%23issuecomment-489439176&data = 02% 7C01% 7C% 7C5a4c31a04c6541d6080608d6d172b36a% 7C84df9e7fe9f640afb435aaaaaaaaaaaa% 7C1% 7C0% 7C636926687892536099 & SData = RdPBMt9fPqsPC1x0FlJ1MQzn8BK6m9lfg7nsT09YIN8% 3D & зарезервирован = 0 , или приглушить нить https://nam05.safelinks.protection.outlook.com/?url=https%3A%2F% 2Fgithub.com% 2Fnotifications% 2Funsubscribe-AUTH% 2FAABUHE2I4F33TX2SZJE2RVDPT377JANCNFSM4EZ4GB5Q & данные = 02% 7C01% 7C% 7C5a4c31a04c6541d6080608d6d172b36a% 7C84df9e7fe9f640afb435aaaaaaaaaaaa% 7C1% 7C0% 7C636926687892546103 & SData = UXiXgRiTo4pAjJVraUqmJmYZibiWMdh9htX2SeFG4JM% 3D & зарезервирован = 0 .

@Elashi это не так, но я мог видеть, что это действительно мощная функция для сценариев MVVM

Если вы хотите поработать над этим, можете ли вы создать проблему с основами того, о чем вы думаете?

Итак, методом проб и ошибок ... Несмотря на то, что в нем есть комментарии о жестах в оболочке 3.2 и в TheLittlePlayground, я не могу, хоть убей, заставить жесты работать на ANDROID с визуальным пакетом.

Я что-то упустил в примечаниях, что жесты Shell + работают только с iphone?

@davidortinau Я знаю, что это всего лишь некоторые спецификации, и он был закрыт на некоторое время, но я надеялся, что вы сможете указать мне в правильном направлении, поскольку в спецификациях указано, что приведенная ниже задача либо завершена, либо находится в списке для разработка:

  • Добавить API для элементов "подменю" для ShellContent ala GPS -> Музыка -> Открыть приложение Music

В настоящее время, поскольку я не могу заставить работать GroupHeaders, я хочу переработать свое FlyoutMenu, чтобы отсортировать его по 6 основным группам, а затем появиться подменю, заполненное FlyoutItems, которые направляют меня к маршрутизации, которую я заранее определил.

Мой вариант использования состоит в том, что у меня есть 50+ вариантов для отображения, и установка их в состояние прокрутки не является дружественным к пользовательскому интерфейсу, но каждая отображаемая опция - это то, что мне нужно, чтобы мои пользователи могли получить эффективный доступ без бесконечной прокрутки. Сортировка по группам на основе общей темы каждого варианта имеет наибольший смысл с точки зрения UI / UX.

Можете ли вы пролить свет на то, где это находится с точки зрения разработки / производства? - или указать мне на кодовую базу, которая его реализует, чтобы я мог учиться? (Я работаю с Xamarin всего 1 месяц, поэтому я все еще новичок в некоторых доступных ресурсах).

@TheBaileyBrew

Я только что погуглил это репо с чем-то, что, скорее всего, могло бы сработать для вашего сценария. Это не будет Shell, но вы, вероятно, можете использовать его в настройке MasterDetailPage.

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

Кроме того, они просто переместили и обновили большую часть своих курсовых материалов в MSFT Learn (которые я просматриваю сам, чтобы заполнить пробелы). Это можно найти здесь: https://docs.microsoft.com/en-us/learn/browse/?products=xamarin

Я бы попробовал пройти через все вышесказанное. Удачи и добро пожаловать на борт!

Привет, ребята, я хочу выбрать файл или фотографии из галереи или внешнего хранилища в
xamarin формирует, кто это файл ковырять? Файл имеет только расширение .PDF. К
выберите оба файла, я использую одну кнопку, пожалуйста, помогите мне !!!

В чт, 23 мая 2019 г., 19:41 Anthony Cool [email protected] написал:

@TheBaileyBrew https://github.com/TheBaileyBrew

Я только что погуглил это репо с чем-то, что могло бы работать для вашего сценария
наверняка. Это не будет Shell, но вы можете использовать его в MasterDetailPage.
настройка наверное.

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

-
Вы получаете это, потому что подписаны на эту беседу.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/xamarin/Xamarin.Forms/issues/2415?email_source=notifications&email_token=AK7KSYK4N3XIVP3IHOBE2P3PW3CKJA5CNFSM4EZ4GB52YY3PNVWWK3TUL52XG43LVMVL7KWWWK3TREXG4DVM7C0C0CM08C08C08C08C08C08C08C0B0CM08C08
или отключить поток
https://github.com/notifications/unsubscribe-auth/AK7KSYI5XKMXD7FC7HZH45LPW3CKJANCNFSM4EZ4GB5Q
.

Привет, ребята, я хочу добавлять вкладки в зависимости от условий, так как я могу добавлять вкладки в оболочке, используя C #, а не в Xaml, а также как добавлять элементы меню.

@TheBaileyBrew

это то, что вы ищете?
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/flyout#flyout -display-options

@BeleShew ваш вопрос, вероятно, лучше подходит для stackoverflow или на forum.xamarin.com

@PWaliaDev, вы можете сделать это с помощью различных коллекций элементов, которые являются частью оболочки.

Shell.Items.Add (новый ShellItem ())
новый ShellItem (). Items.add (новый ShellSection ())
новый ShellSection (). Items.Add (новый ShellContent ())

Хотя я предполагаю, что если мы исправим эту проблему
https://github.com/xamarin/Xamarin.Forms/issues/5428

что подойдет вашему сценарию?

@PureWeen - У меня есть параметры отображения, установленные для вашей ссылки, но то, с чем я борюсь, ближе к тому, с чем имеет дело

Исправление № 5428 подошло бы тому, чего я хочу достичь.

В моем приложении есть пользователи с множеством ролей / доступа, и мне нужно программно отображать пункты меню только для авторизованных пользователей (я не хочу, чтобы пользователи видели то, что они _ не могут _ делать, а только то, что они могут.

Хотя я играл с этим, пытаясь выяснить, можно ли проверить параметры моего меню и добавить, а не скрыть, как это делает этот код (но мне пришлось бы перебирать все возможные маршруты и параметры меню, которые съели бы время загрузки:

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 великолепна в теории, но не в практическом плане без этих обязательных функций.

  1. Добавлять / удалять элементы оболочки динамически в зависимости от роли пользователя
  2. Сценарий входа / выхода или два отдельных маршрута навигации в зависимости от условий.
  3. По желанию, поддержка других фреймворков MVVM, таких как Prism

Невозможно использовать Shell в бизнес-ориентированных приложениях, пока не будут предоставлены функции 1 и 2.

@ Im-PJ Почему вы думаете, что 1 и 2 невозможны? (почти уверен, что они есть)

3 находится в стадии разработки и отслеживается здесь .

Кто-нибудь знает, можно ли получить событие касания из вкладки App Shell?
связанный вопрос на форуме: https://forums.xamarin.com/discussion/159748/app-shell-pop-to-root-on-tab-tap

Полностью согласен с @ Im-PJ и не понимаю, почему эти функции специально не предусмотрены. Это основная причина появления такого инструмента, как Shell. Кто угодно может создать выдвигающееся меню!

@dotMorten, возможно, вы можете сделать 1 или 2 с помощью обширного C # и взлома, но я не могу найти НИКАКИХ примеров или упоминания привязки / отключения / скрытия / добавления элементов оболочки во время выполнения. Кажется, что динамические возможности были бы основной целью этого инструмента. Создание XML-представления вместе с некоторыми функциями управления путями - это минимум, которого достаточно, чтобы передать его маркетологам, но не достаточно, чтобы его можно было использовать в реальном полнофункциональном мобильном приложении.

@ Im-PJ

не могли бы вы немного рассказать, чем они отличаются?

Добавлять / удалять элементы оболочки динамически в зависимости от роли пользователя
Сценарий входа / выхода

В настоящее время вы можете выполнить сценарий входа / выхода, используя TabBar или скрывая всплывающую навигацию, если вы находитесь на странице входа.

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

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

Если вы находитесь на странице входа в систему, единственный способ уйти - использовать код.

Здесь проводится работа по предоставлению привязываемого свойства IsVisible.
https://github.com/xamarin/Xamarin.Forms/tree/shell_isvisible

Просто нужно немного доработать, прежде чем создавать PR.

два отдельных навигационных маршрута в зависимости от условий.

Можете ли вы привести примеры того, что вы пытаетесь сделать и не можете сделать в настоящее время?

hoi1
Я использую оболочку Xamarin.Form Shell

Пример ссылки: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/flyout

Помогите, пожалуйста. Как отобразить панель вкладок на странице «О программе»?

Мне нужно иметь две страницы оболочки одновременно.
Один для меню очистки со страницей как домашней, настройками, выходом из системы и т. Д.
Один для страниц с вкладками, которые нужно выталкивать из дома
А пока я должен использовать "старый способ"

Мне нужно иметь две страницы оболочки одновременно.
Один для меню очистки со страницей как домашней, настройками, выходом из системы и т. Д.
Один для страниц с вкладками, которые нужно выталкивать из дома
А пока я должен использовать "старый способ"

При использовании страницы с вкладками не может отображаться всплывающее окно. На этот раз я хочу показать всплывающее меню и панель вкладок.

Я поместил все страницы вчтобы на страницах отображалась панель вкладок, но я хочу, чтобы на панели вкладок было только 4 элемента (не хочу отображать дополнительную вкладку). Как сделать?

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

Мне нужно иметь две страницы оболочки одновременно.
Один для меню очистки со страницей как домашней, настройками, выходом из системы и т. Д.
Один для страниц с вкладками, которые нужно выталкивать из дома
А пока я должен использовать "старый способ"

При использовании страницы с вкладками не может отображаться всплывающее окно. На этот раз я хочу показать всплывающее меню и панель вкладок.

Я помещаю все страницы в так, чтобы на страницах отображалась панель вкладок, но я хочу, чтобы на панели вкладок было только 4 элемента (не хочу отображать дополнительную вкладку). Как сделать?

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

К сожалению, я не могу использовать Shell
У меня все еще есть MasterDetailPage и TabbedPage в том же приложении (в iOS у меня есть верхние страницы с вкладками, использующие плагин Naxam.TopTabbedPage.Forms)
Это был мой старый билет

Была ли эта страница полезной?
0 / 5 - 0 рейтинги