Elementos específicos à plataforma
Os itens específicos 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 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, esse é o
Xamarin.Forms.PlatformConfiguration.iOSSpecific
namespace. - No Android, esse é o
Xamarin.Forms.PlatformConfiguration.AndroidSpecific
namespace. Para Android AppCompat, este é oXamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat
namespace. - Na Plataforma Universal do Windows, esse é o
Xamarin.Forms.PlatformConfiguration.WindowsSpecific
namespace.
- No iOS, esse é o
- Aplique o específico da plataforma a partir de XAML 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 uma plataforma específica em uma plataforma onde ela 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.
Específicos da plataforma consumidos por meio dos objetos de retorno IPlatformElementConfiguration
da On<T>
API de código fluente. Isso permite que vários específicos da plataforma sejam invocados no mesmo objeto com o método em cascata.
Para obter mais informações sobre as especificidades de plataforma fornecidas pelo Xamarin.Forms, consulte Especificações da plataforma iOS, Específicas da plataforma Android e Específicas da plataforma Windows.
Criando especificidades da plataforma
Os fornecedores podem criar suas próprias especificações de plataforma com o Effects. Um Efeito 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 Criando um efeito.
- Crie uma classe específica da plataforma que irá 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 a específica da plataforma seja consumida 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 a plataforma específica seja consumida 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 da exposição de 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 plataformas específicas, para facilitar o consumo pelos usuários. Embora os usuários possam optar por criar suas próprias especificações de plataforma, deve-se notar 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 a Shadow
plataforma específica em cada plataforma, para facilitar o entendimento. No entanto, além de cada implementação de Effect 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 Effect 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 Effect associado e específico da Shadow
plataforma.
Adicionando uma propriedade anexada
Uma propriedade anexada deve ser adicionada à plataforma específica 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
Effect 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
ou DetachEffect
método para adicionar ou remover o efeito com base no valor da IsShadowed
propriedade anexada. O Effect é 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 Criando 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 à plataforma específica 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 e SetIsShadowed
extension 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
esteja definida como true
, e desde que o Shadow
específico da plataforma tenha sido invocado na mesma plataforma para a qual o Effect é implementado. Essa verificação é realizada com o OnThisPlatform
método.
Se o valor da propriedade anexada Shadow.IsShadowed
for alterado em tempo de execução, o Efeito precisará responder removendo a sombra. Portanto, uma versão substituída do método é usada para responder à alteração de OnElementPropertyChanged
propriedade vinculá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);