Особенности платформы
Специальные платформы позволяют использовать функциональные возможности, доступные только на определенной платформе, не реализуя пользовательские отрисовщики или эффекты.
Процесс использования конкретной платформы с помощью XAML или через API свободного кода выглядит следующим образом:
xmlns
Добавьте объявление илиusing
директиву дляXamarin.Forms.PlatformConfiguration
пространства имен.xmlns
Добавьте объявление илиusing
директиву для пространства имен, содержащего функциональные возможности для конкретной платформы:- В iOS это
Xamarin.Forms.PlatformConfiguration.iOSSpecific
пространство имен. - В Android это
Xamarin.Forms.PlatformConfiguration.AndroidSpecific
пространство имен. Для Android AppCompat этоXamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat
пространство имен. - В универсальная платформа Windows это
Xamarin.Forms.PlatformConfiguration.WindowsSpecific
пространство имен.
- В iOS это
- Примените платформу из XAML или из кода с помощью свободного
On<T>
API. ЗначениеT
может быть типомiOS
Android
илиWindows
типомXamarin.Forms.PlatformConfiguration
из пространства имен.
Примечание.
Обратите внимание, что попытка использования конкретной платформы на платформе, в которой она недоступна, не приведет к ошибке. Вместо этого код будет выполняться без применения конкретной платформы.
Специальные платформы, используемые через возвращаемые IPlatformElementConfiguration
объекты API свободного On<T>
кода. Это позволяет вызывать несколько конкретных платформ в одном объекте с каскадным методом.
Дополнительные сведения о конкретных платформах, предоставляемых в iOS Platform-Specifics, Android Platform-Specifics и Windows Platform-Specifics.Xamarin.Forms
Создание конкретных платформ
Поставщики могут создавать собственные платформы с помощью эффектов. Эффект предоставляет определенные функциональные возможности, которые затем предоставляются через платформу. Результатом является эффект, который может быть проще использовать через XAML, а также через простой API кода.
Процесс создания конкретной платформы выглядит следующим образом:
- Реализуйте определенные функциональные возможности в качестве эффекта. Дополнительные сведения см. в разделе "Создание эффекта".
- Создайте класс, зависящий от платформы, который будет предоставлять эффект. Дополнительные сведения см. в разделе "Создание класса для конкретной платформы".
- В классе для конкретной платформы реализуйте присоединенное свойство, чтобы разрешить использование конкретной платформы с помощью XAML. Дополнительные сведения см. в разделе "Добавление присоединенного свойства".
- В классе, зависящего от платформы, реализуйте методы расширения, чтобы разрешить использование конкретной платформы через API свободного кода. Дополнительные сведения см. в разделе "Добавление методов расширения".
- Измените реализацию эффектов, чтобы эффект применялся только в том случае, если платформа была вызвана на той же платформе, что и эффект. Дополнительные сведения см. в разделе "Создание эффекта".
Результат предоставления эффекта в виде платформы заключается в том, что эффект может быть проще использовать через 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);