Поделиться через


Особенности платформы

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

Процесс использования конкретной платформы с помощью XAML или через API свободного кода выглядит следующим образом:

  1. xmlns Добавьте объявление или using директиву для Xamarin.Forms.PlatformConfiguration пространства имен.
  2. xmlns Добавьте объявление или using директиву для пространства имен, содержащего функциональные возможности для конкретной платформы:
    1. В iOS это Xamarin.Forms.PlatformConfiguration.iOSSpecific пространство имен.
    2. В Android это Xamarin.Forms.PlatformConfiguration.AndroidSpecific пространство имен. Для Android AppCompat это Xamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat пространство имен.
    3. В универсальная платформа Windows это Xamarin.Forms.PlatformConfiguration.WindowsSpecific пространство имен.
  3. Примените платформу из XAML или из кода с помощью свободного On<T> API. Значение T может быть типом iOSAndroidили Windows типом Xamarin.Forms.PlatformConfiguration из пространства имен.

Примечание.

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

Специальные платформы, используемые через возвращаемые IPlatformElementConfiguration объекты API свободного On<T> кода. Это позволяет вызывать несколько конкретных платформ в одном объекте с каскадным методом.

Дополнительные сведения о конкретных платформах, предоставляемых в iOS Platform-Specifics, Android Platform-Specifics и Windows Platform-Specifics.Xamarin.Forms

Создание конкретных платформ

Поставщики могут создавать собственные платформы с помощью эффектов. Эффект предоставляет определенные функциональные возможности, которые затем предоставляются через платформу. Результатом является эффект, который может быть проще использовать через XAML, а также через простой API кода.

Процесс создания конкретной платформы выглядит следующим образом:

  1. Реализуйте определенные функциональные возможности в качестве эффекта. Дополнительные сведения см. в разделе "Создание эффекта".
  2. Создайте класс, зависящий от платформы, который будет предоставлять эффект. Дополнительные сведения см. в разделе "Создание класса для конкретной платформы".
  3. В классе для конкретной платформы реализуйте присоединенное свойство, чтобы разрешить использование конкретной платформы с помощью XAML. Дополнительные сведения см. в разделе "Добавление присоединенного свойства".
  4. В классе, зависящего от платформы, реализуйте методы расширения, чтобы разрешить использование конкретной платформы через API свободного кода. Дополнительные сведения см. в разделе "Добавление методов расширения".
  5. Измените реализацию эффектов, чтобы эффект применялся только в том случае, если платформа была вызвана на той же платформе, что и эффект. Дополнительные сведения см. в разделе "Создание эффекта".

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

Примечание.

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

Пример приложения демонстрирует Shadow платформу, которая добавляет тень к тексту, отображаемого элементом Label управления:

Теневая платформа

Пример приложения реализует Shadow платформу для каждой платформы для простоты понимания. Однако помимо каждой реализации эффекта для конкретной платформы реализация класса Shadow в значительной степени идентична для каждой платформы. Поэтому в этом руководстве основное внимание уделяется реализации класса Теневого класса и связанному эффекту на одной платформе.

Дополнительные сведения о эффектах см. в разделе "Настройка элементов управления с помощью эффектов".

Создание класса для конкретной платформы

Для конкретной public static платформы создается класс:

namespace MyCompany.Forms.PlatformConfiguration.iOS
{
  public static Shadow
  {
    ...
  }
}

В следующих разделах рассматривается реализация конкретной платформы и связанного Shadow эффекта.

Добавление присоединенного свойства

Присоединенное свойство необходимо добавить в платформу Shadow , чтобы разрешить потребление с помощью XAML:

namespace MyCompany.Forms.PlatformConfiguration.iOS
{
    using System.Linq;
    using Xamarin.Forms;
    using Xamarin.Forms.PlatformConfiguration;
    using FormsElement = Xamarin.Forms.Label;

    public static class Shadow
    {
        const string EffectName = "MyCompany.LabelShadowEffect";

        public static readonly BindableProperty IsShadowedProperty =
            BindableProperty.CreateAttached("IsShadowed",
                                            typeof(bool),
                                            typeof(Shadow),
                                            false,
                                            propertyChanged: OnIsShadowedPropertyChanged);

        public static bool GetIsShadowed(BindableObject element)
        {
            return (bool)element.GetValue(IsShadowedProperty);
        }

        public static void SetIsShadowed(BindableObject element, bool value)
        {
            element.SetValue(IsShadowedProperty, value);
        }

        ...

        static void OnIsShadowedPropertyChanged(BindableObject element, object oldValue, object newValue)
        {
            if ((bool)newValue)
            {
                AttachEffect(element as FormsElement);
            }
            else
            {
                DetachEffect(element as FormsElement);
            }
        }

        static void AttachEffect(FormsElement element)
        {
            IElementController controller = element;
            if (controller == null || controller.EffectIsAttached(EffectName))
            {
                return;
            }
            element.Effects.Add(Effect.Resolve(EffectName));
        }

        static void DetachEffect(FormsElement element)
        {
            IElementController controller = element;
            if (controller == null || !controller.EffectIsAttached(EffectName))
            {
                return;
            }

            var toRemove = element.Effects.FirstOrDefault(e => e.ResolveId == Effect.Resolve(EffectName).ResolveId);
            if (toRemove != null)
            {
                element.Effects.Remove(toRemove);
            }
        }
    }
}

Присоединенное IsShadowed свойство используется для добавления MyCompany.LabelShadowEffect эффекта и удаления из него элемента управления Shadow , к которому подключен класс. Это присоединенное свойство регистрирует метод OnIsShadowedPropertyChanged, который будет выполняться при изменении значения свойства. В свою очередь, этот метод вызывает AttachEffect или DetachEffect метод для добавления или удаления эффекта на основе значения присоединенного IsShadowed свойства. Эффект добавляется или удаляется из элемента управления путем изменения коллекции элемента управления Effects .

Примечание.

Обратите внимание, что эффект разрешается путем указания значения, сцепления имени группы разрешения и уникального идентификатора, указанного в реализации Effect. Дополнительные сведения см. в разделе "Создание эффекта".

Дополнительные сведения о присоединенных свойствах см. в разделе Присоединенные свойства.

Добавление методов расширения

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

namespace MyCompany.Forms.PlatformConfiguration.iOS
{
    using System.Linq;
    using Xamarin.Forms;
    using Xamarin.Forms.PlatformConfiguration;
    using FormsElement = Xamarin.Forms.Label;

    public static class Shadow
    {
        ...
        public static bool IsShadowed(this IPlatformElementConfiguration<iOS, FormsElement> config)
        {
            return GetIsShadowed(config.Element);
        }

        public static IPlatformElementConfiguration<iOS, FormsElement> SetIsShadowed(this IPlatformElementConfiguration<iOS, FormsElement> config, bool value)
        {
            SetIsShadowed(config.Element, value);
            return config;
        }
        ...
    }
}

Методы IsShadowed расширения SetIsShadowed вызывают методы получения и задания доступа для присоединенного IsShadowed свойства соответственно. Каждый метод расширения работает с типом IPlatformElementConfiguration<iOS, FormsElement> , который указывает, что для конкретной платформы можно вызывать Label экземпляры из iOS.

Создание эффекта

Платформа Shadow добавляет объект MyCompany.LabelShadowEffect в объект Labelи удаляет его. В следующем примере кода показана реализация класса LabelShadowEffect для проекта на платформе iOS:

[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(LabelShadowEffect), "LabelShadowEffect")]
namespace ShadowPlatformSpecific.iOS
{
    public class LabelShadowEffect : PlatformEffect
    {
        protected override void OnAttached()
        {
            UpdateShadow();
        }

        protected override void OnDetached()
        {
        }

        protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
        {
            base.OnElementPropertyChanged(args);

            if (args.PropertyName == Shadow.IsShadowedProperty.PropertyName)
            {
                UpdateShadow();
            }
        }

        void UpdateShadow()
        {
            try
            {
                if (((Label)Element).OnThisPlatform().IsShadowed())
                {
                    Control.Layer.CornerRadius = 5;
                    Control.Layer.ShadowColor = UIColor.Black.CGColor;
                    Control.Layer.ShadowOffset = new CGSize(5, 5);
                    Control.Layer.ShadowOpacity = 1.0f;
                }
                else if (!((Label)Element).OnThisPlatform().IsShadowed())
                {
                    Control.Layer.ShadowOpacity = 0;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
            }
        }
    }
}

Метод UpdateShadow задает Control.Layer свойства для создания тени, при условии, что IsShadowed присоединенное свойство имеет trueзначение, и при условии, что Shadow платформа была вызвана на той же платформе, для которую реализован эффект. Эта проверка выполняется с OnThisPlatform помощью метода.

Если значение присоединенного Shadow.IsShadowed свойства изменяется во время выполнения, эффект должен реагировать, удаляя тень. Поэтому переопределенная версия OnElementPropertyChanged метода используется для реагирования на изменение привязываемого свойства путем вызова UpdateShadow метода.

Дополнительные сведения о создании эффекта см. в разделе "Создание эффекта" и "Передача параметров эффекта" в качестве присоединенных свойств.

Использование конкретной платформы

Для Shadow конкретной платформы используется в XAML, задав Shadow.IsShadowed присоединенное свойство значением boolean :

<ContentPage xmlns:ios="clr-namespace:MyCompany.Forms.PlatformConfiguration.iOS" ...>
  ...
  <Label Text="Label Shadow Effect" ios:Shadow.IsShadowed="true" ... />
  ...
</ContentPage>

Кроме того, его можно использовать из C# с помощью api fluent:

using Xamarin.Forms.PlatformConfiguration;
using MyCompany.Forms.PlatformConfiguration.iOS;

...

shadowLabel.On<iOS>().SetIsShadowed(true);