Elementos específicos à plataforma
As especificações da plataforma permitem que você consuma funcionalidades que só estão disponíveis em uma plataforma específica, sem implementar renderizadores ou efeitos personalizados.
O processo para consumir uma plataforma específica por meio de XAML ou por meio da API de código fluente é o seguinte:
- Adicione uma
xmlns
declaração ouusing
diretiva para oXamarin.Forms.PlatformConfiguration
namespace. - Adicione uma
xmlns
declaração ouusing
diretiva para o namespace que contém a funcionalidade específica da plataforma:- No iOS, este é o
Xamarin.Forms.PlatformConfiguration.iOSSpecific
namespace. - No Android, esse é o
Xamarin.Forms.PlatformConfiguration.AndroidSpecific
namespace. Para Android AppCompat, esse é oXamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat
namespace. - Na Plataforma Universal do Windows, esse é o
Xamarin.Forms.PlatformConfiguration.WindowsSpecific
namespace.
- No iOS, este é o
- Aplique o XAML específico da plataforma ou do código com a
On<T>
API fluente. O valor deT
pode ser oiOS
,Android
, ouWindows
tipos doXamarin.Forms.PlatformConfiguration
namespace.
Observação
Observe que a tentativa de consumir um específico da plataforma em uma plataforma em que ele não está disponível não resultará em um erro. Em vez disso, o código será executado sem que o específico da plataforma seja aplicado.
Objetos de retorno IPlatformElementConfiguration
específicos da plataforma consumidos por meio da On<T>
API de código fluente. Isso permite que várias especificações da plataforma sejam invocadas no mesmo objeto com o método em cascata.
Para obter mais informações sobre as especificações da plataforma fornecidas pelo Xamarin.Forms, consulte Especificações da plataforma iOS, Especificações da plataforma Android e Especificações da plataforma Windows.
Criando especificações da plataforma
Os fornecedores podem criar suas próprias especificações de plataforma com o Effects. Um Effect fornece a funcionalidade específica, que é exposta por meio de uma plataforma específica. O resultado é um Effect que pode ser consumido mais facilmente por meio de XAML e por meio de uma API de código fluente.
O processo para criar uma plataforma específica é o seguinte:
- Implemente a funcionalidade específica como um efeito. Para obter mais informações, consulte Criação de um efeito.
- Crie uma classe específica da plataforma que exporá o Efeito. Para obter mais informações, consulte Criando uma classe específica da plataforma.
- Na classe específica da plataforma, implemente uma propriedade anexada para permitir que o específico da plataforma seja consumido por meio de XAML. Para obter mais informações, consulte Adicionando uma propriedade anexada.
- Na classe específica da plataforma, implemente métodos de extensão para permitir que o específico da plataforma seja consumido por meio de uma API de código fluente. Para obter mais informações, consulte Adicionando métodos de extensão.
- Modifique a implementação do Efeito para que o Efeito só seja aplicado se o específico da plataforma tiver sido invocado na mesma plataforma que o Efeito. Para obter mais informações, consulte Criando o efeito.
O resultado de expor um Effect como específico da plataforma é que o Effect pode ser consumido mais facilmente por meio de XAML e por meio de uma API de código fluente.
Observação
Prevê-se que os fornecedores usem essa técnica para criar suas próprias especificações da plataforma, para facilitar o consumo pelos usuários. Embora os usuários possam optar por criar suas próprias especificações da plataforma, deve-se observar que isso requer mais código do que criar e consumir um Effect.
O aplicativo de exemplo demonstra uma Shadow
plataforma específica que adiciona uma sombra ao texto exibido por um Label
controle:
O aplicativo de exemplo implementa o específico da Shadow
plataforma em cada plataforma, para facilitar a compreensão. No entanto, além de cada implementação de efeito específica da plataforma, a implementação da classe Shadow é praticamente idêntica para cada plataforma. Portanto, este guia se concentra na implementação da classe Shadow e no efeito associado em uma única plataforma.
Para obter mais informações sobre efeitos, consulte Personalizando controles com efeitos.
Criando uma classe específica da plataforma
Uma plataforma específica é criada como uma public static
classe:
namespace MyCompany.Forms.PlatformConfiguration.iOS
{
public static Shadow
{
...
}
}
As seções a seguir discutem a implementação do Shadow
Efeito específico da plataforma e associado.
Adicionando uma propriedade anexada
Uma propriedade anexada deve ser adicionada ao específico da plataforma para permitir o Shadow
consumo por meio de 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);
}
}
}
}
A IsShadowed
propriedade anexada é usada para adicionar o MyCompany.LabelShadowEffect
efeito e removê-lo do controle ao qual a Shadow
classe está anexada. Essa propriedade anexada registra o método OnIsShadowedPropertyChanged
que será executado quando o valor da propriedade for alterado. Por sua vez, esse método chama o AttachEffect
método or DetachEffect
para adicionar ou remover o efeito com base no valor da IsShadowed
propriedade anexada. O efeito é adicionado ou removido do controle modificando a coleção do Effects
controle.
Observação
Observe que o Efeito é resolvido especificando um valor que é uma concatenação do nome do grupo de resolução e do identificador exclusivo especificado na implementação do Efeito. Para obter mais informações, consulte Criação de um efeito.
Para obter mais informações sobre as propriedades anexadas, confira Propriedades anexadas.
Adicionando métodos de extensão
Os métodos de extensão devem ser adicionados ao específico da plataforma para permitir o Shadow
consumo por meio de uma API de código fluente:
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;
}
...
}
}
Os IsShadowed
métodos de extensão e SetIsShadowed
invocam os acessadores get e set para a IsShadowed
propriedade anexada, respectivamente. Cada método de extensão opera no IPlatformElementConfiguration<iOS, FormsElement>
tipo, que especifica que o específico da plataforma pode ser invocado em Label
instâncias do iOS.
Criando o efeito
O Shadow
específico da plataforma adiciona o MyCompany.LabelShadowEffect
a um Label
e o remove. O exemplo de código a seguir mostra a implementação de LabelShadowEffect
para o projeto do 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);
}
}
}
}
O UpdateShadow
método define Control.Layer
propriedades para criar a sombra, desde que a propriedade anexada IsShadowed
seja definida como true
e desde que o específico da Shadow
plataforma tenha sido invocado na mesma plataforma para a qual o efeito é implementado. Esta verificação é realizada com o OnThisPlatform
método.
Se o valor da propriedade anexada Shadow.IsShadowed
for alterado no tempo de execução, o efeito precisará responder removendo a sombra. Portanto, uma versão substituída do OnElementPropertyChanged
método é usada para responder à alteração da propriedade associável chamando o UpdateShadow
método.
Para obter mais informações sobre como criar um efeito, consulte Criando um efeito e Passando parâmetros de efeito como propriedades anexadas.
Consumindo o específico da plataforma
O Shadow
específico da plataforma é consumido em XAML definindo a propriedade anexada Shadow.IsShadowed
como um boolean
valor:
<ContentPage xmlns:ios="clr-namespace:MyCompany.Forms.PlatformConfiguration.iOS" ...>
...
<Label Text="Label Shadow Effect" ios:Shadow.IsShadowed="true" ... />
...
</ContentPage>
Como alternativa, ele pode ser consumido do C# usando a API fluente:
using Xamarin.Forms.PlatformConfiguration;
using MyCompany.Forms.PlatformConfiguration.iOS;
...
shadowLabel.On<iOS>().SetIsShadowed(true);