Xamarin.Forms Funkcja RoundEffect wielokrotnego użytku
Ważne
Nie trzeba już używać RoundEffect
kontrolki do renderowania kontrolki jako okręgu. Najnowszą zalecaną metodą jest przycinanie kontrolki przy użyciu elementu EllipseGeometry
. Aby uzyskać więcej informacji, zobacz Clip with a Geometry (Tworzenie wycinków za pomocą geometrii).
Funkcja RoundEffect upraszcza renderowanie dowolnej kontrolki pochodzącej z VisualElement
okręgu. Ten efekt może służyć do tworzenia okrągłych obrazów, przycisków i innych kontrolek:
Tworzenie udostępnionego elementu RoutingEffect
Klasa efektu musi zostać utworzona w projekcie udostępnionym, aby utworzyć efekt międzyplatformowy. Przykładowa aplikacja tworzy pustą RoundEffect
klasę pochodzącą RoutingEffect
z klasy :
public class RoundEffect : RoutingEffect
{
public RoundEffect() : base($"Xamarin.{nameof(RoundEffect)}")
{
}
}
Ta klasa umożliwia projektowi udostępnionemu rozpoznawanie odwołań do efektu w kodzie lub XAML, ale nie zapewnia żadnych funkcji. Efekt musi mieć implementacje dla każdej platformy.
Implementowanie efektu systemu Android
Projekt platformy systemu Android definiuje klasę pochodzącą RoundEffect
z PlatformEffect
klasy . Ta klasa jest oznaczona atrybutami assembly
, które umożliwiają Xamarin.Forms rozpoznawanie klasy efektu:
[assembly: ResolutionGroupName("Xamarin")]
[assembly: ExportEffect(typeof(RoundEffectDemo.Droid.RoundEffect), nameof(RoundEffectDemo.Droid.RoundEffect))]
namespace RoundEffectDemo.Droid
{
public class RoundEffect : PlatformEffect
{
// ...
}
}
Platforma Android używa koncepcji elementu OutlineProvider
, aby zdefiniować krawędzie kontrolki. Przykładowy projekt zawiera klasę pochodzącą CornerRadiusProvider
ViewOutlineProvider
z klasy:
class CornerRadiusOutlineProvider : ViewOutlineProvider
{
Element element;
public CornerRadiusOutlineProvider(Element formsElement)
{
element = formsElement;
}
public override void GetOutline(Android.Views.View view, Outline outline)
{
float scale = view.Resources.DisplayMetrics.Density;
double width = (double)element.GetValue(VisualElement.WidthProperty) * scale;
double height = (double)element.GetValue(VisualElement.HeightProperty) * scale;
float minDimension = (float)Math.Min(height, width);
float radius = minDimension / 2f;
Rect rect = new Rect(0, 0, (int)width, (int)height);
outline.SetRoundRect(rect, radius);
}
}
Ta klasa używa Width
właściwości Xamarin.FormsElement
i Height
wystąpienia do obliczania promienia, który jest połowę najkrótszego wymiaru.
Po zdefiniowaniu RoundEffect
dostawcy konspektu klasa może jej używać w celu zaimplementowania efektu:
public class RoundEffect : PlatformEffect
{
ViewOutlineProvider originalProvider;
Android.Views.View effectTarget;
protected override void OnAttached()
{
try
{
effectTarget = Control ?? Container;
originalProvider = effectTarget.OutlineProvider;
effectTarget.OutlineProvider = new CornerRadiusOutlineProvider(Element);
effectTarget.ClipToOutline = true;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to set corner radius: {ex.Message}");
}
}
protected override void OnDetached()
{
if(effectTarget != null)
{
effectTarget.OutlineProvider = originalProvider;
effectTarget.ClipToOutline = false;
}
}
}
Metoda jest wywoływana OnAttached
, gdy efekt jest dołączony do elementu. Istniejący OutlineProvider
obiekt jest zapisywany, aby można go było przywrócić po odłączeniu efektu. Nowe wystąpienie obiektu CornerRadiusOutlineProvider
jest używane jako OutlineProvider
element i ClipToOutline
jest ustawione na wartość true, aby przycinać przepełnianie elementów obramowaniem konspektu.
Metoda OnDetatched
jest wywoływana, gdy efekt zostanie usunięty z elementu i przywróci oryginalną OutlineProvider
wartość.
Uwaga
W zależności od typu Control
elementu właściwość może lub nie może mieć wartości null. Control
Jeśli właściwość nie ma wartości null, zaokrąglone rogi można zastosować bezpośrednio do kontrolki. Jeśli jednak ma wartość null, zaokrąglone narożniki muszą zostać zastosowane do Container
obiektu. Pole effectTarget
umożliwia zastosowanie efektu do odpowiedniego obiektu.
Implementowanie efektu systemu iOS
Projekt platformy systemu iOS definiuje klasę pochodzącą RoundEffect
z PlatformEffect
klasy . Ta klasa jest oznaczona atrybutami assembly
, które umożliwiają Xamarin.Forms rozpoznawanie klasy efektu:
[assembly: ResolutionGroupName("Xamarin")]
[assembly: ExportEffect(typeof(RoundEffectDemo.iOS.RoundEffect), nameof(RoundEffectDemo.iOS.RoundEffect))]
namespace RoundEffectDemo.iOS
{
public class RoundEffect : PlatformEffect
{
// ...
}
W systemie iOS kontrolki mają Layer
właściwość, która ma CornerRadius
właściwość . Implementacja RoundEffect
klasy w systemie iOS oblicza odpowiedni promień rogu i aktualizuje właściwość warstwy CornerRadius
:
public class RoundEffect : PlatformEffect
{
nfloat originalRadius;
UIKit.UIView effectTarget;
protected override void OnAttached()
{
try
{
effectTarget = Control ?? Container;
originalRadius = effectTarget.Layer.CornerRadius;
effectTarget.ClipsToBounds = true;
effectTarget.Layer.CornerRadius = CalculateRadius();
}
catch (Exception ex)
{
Console.WriteLine($"Failed to set corner radius: {ex.Message}");
}
}
protected override void OnDetached()
{
if (effectTarget != null)
{
effectTarget.ClipsToBounds = false;
if (effectTarget.Layer != null)
{
effectTarget.Layer.CornerRadius = originalRadius;
}
}
}
float CalculateRadius()
{
double width = (double)Element.GetValue(VisualElement.WidthRequestProperty);
double height = (double)Element.GetValue(VisualElement.HeightRequestProperty);
float minDimension = (float)Math.Min(height, width);
float radius = minDimension / 2f;
return radius;
}
}
Metoda CalculateRadius
oblicza promień na podstawie minimalnego Xamarin.FormsElement
wymiaru . Metoda OnAttached
jest wywoływana, gdy efekt jest dołączony do kontrolki i aktualizuje właściwość warstwy CornerRadius
. Ustawia ClipToBounds
właściwość na true
tak przepełnione elementy są przycięte do obramowań kontrolki. Metoda OnDetatched
jest wywoływana, gdy efekt jest usuwany z kontrolki i odwraca te zmiany, przywracając oryginalny promień rogu.
Uwaga
W zależności od typu Control
elementu właściwość może lub nie może mieć wartości null. Control
Jeśli właściwość nie ma wartości null, zaokrąglone rogi można zastosować bezpośrednio do kontrolki. Jeśli jednak ma wartość null, zaokrąglone narożniki muszą zostać zastosowane do Container
obiektu. Pole effectTarget
umożliwia zastosowanie efektu do odpowiedniego obiektu.
Korzystanie z efektu
Po zaimplementowaniu efektu na różnych platformach można go używać za pomocą Xamarin.Forms kontrolek. Typowym zastosowaniem obiektu RoundEffect
jest tworzenie obiektu cyklicznego Image
. Poniższy kod XAML pokazuje efekt stosowany do Image
wystąpienia:
<Image Source=outdoors"
HeightRequest="100"
WidthRequest="100">
<Image.Effects>
<local:RoundEffect />
</Image.Effects>
</Image>
Efekt można również zastosować w kodzie:
var image = new Image
{
Source = ImageSource.FromFile("outdoors"),
HeightRequest = 100,
WidthRequest = 100
};
image.Effects.Add(new RoundEffect());
Klasę RoundEffect
można zastosować do dowolnej kontrolki pochodzącej z klasy VisualElement
.
Uwaga
Aby efekt obliczał prawidłowy promień, kontrolka, która jest stosowana, musi mieć jawne ustalanie rozmiaru. W związku z HeightRequest
tym należy zdefiniować właściwości i WidthRequest
. Jeśli kontrolka, której dotyczy problem, pojawi się w obiekcie StackLayout
, jej HorizontalOptions
właściwość nie powinna używać jednej z wartości Rozwiń , takich jak LayoutOptions.CenterAndExpand
lub nie będzie miała dokładnych wymiarów.