Dostosowywanie obiektu ContentPage
ContentPage to element wizualny, który wyświetla pojedynczy widok i zajmuje większość ekranu. W tym artykule pokazano, jak utworzyć niestandardowy moduł renderujący dla strony ContentPage, umożliwiając deweloperom zastąpienie domyślnego renderowania natywnego przy użyciu własnego dostosowania specyficznego dla platformy.
Każda Xamarin.Forms kontrolka ma towarzyszący renderer dla każdej platformy, która tworzy wystąpienie kontrolki natywnej. Gdy element ContentPage
jest renderowany przez aplikację Xamarin.Forms , w systemie iOS PageRenderer
klasę tworzy wystąpienie, co z kolei tworzy wystąpienie kontrolki natywnej UIViewController
. Na platformie PageRenderer
Android klasa tworzy wystąpienie kontrolki ViewGroup
. W platforma uniwersalna systemu Windows (UWP) PageRenderer
klasa tworzy wystąpienie kontrolkiFrameworkElement
. Aby uzyskać więcej informacji na temat klasy renderera i natywnych kontrolek mapowanych Xamarin.Forms na, zobacz Renderer Base Classes and Native Controls (Klasy bazowe modułu renderowania i kontrolki natywne).
Na poniższym diagramie przedstawiono relację między kontrolkami ContentPage
macierzystymi i odpowiadającymi im kontrolkami natywnymi, które je implementują:
Proces renderowania można wykorzystać w celu zaimplementowania dostosowań specyficznych dla platformy przez utworzenie niestandardowego modułu renderowania dla elementu na ContentPage
każdej platformie. Proces wykonywania tej czynności jest następujący:
- Utwórz Xamarin.Forms stronę.
- Zużyj stronę z witryny Xamarin.Forms.
- Utwórz niestandardowy moduł renderowania dla strony na każdej platformie.
Każdy element zostanie omówiony z kolei, aby zaimplementować element CameraPage
, który zapewnia kanał informacyjny kamery na żywo i możliwość przechwytywania zdjęcia.
Xamarin.Forms Tworzenie strony
Niezrealizowanych ContentPage
można dodać do udostępnionego Xamarin.Forms projektu, jak pokazano w poniższym przykładzie kodu XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CustomRenderer.CameraPage">
<ContentPage.Content>
</ContentPage.Content>
</ContentPage>
Podobnie plik związany z kodem dla obiektu ContentPage
powinien również pozostać niezmieniony, jak pokazano w poniższym przykładzie kodu:
public partial class CameraPage : ContentPage
{
public CameraPage ()
{
// A custom renderer is used to display the camera UI
InitializeComponent ();
}
}
Poniższy przykład kodu pokazuje, jak można utworzyć stronę w języku C#:
public class CameraPageCS : ContentPage
{
public CameraPageCS ()
{
}
}
Wystąpienie CameraPage
klasy będzie używane do wyświetlania kanału informacyjnego kamery na żywo na każdej platformie. Dostosowanie kontrolki zostanie przeprowadzone w niestandardowym module renderowania, więc w klasie nie jest wymagana żadna dodatkowa implementacja CameraPage
.
Korzystanie ze Xamarin.Forms strony
Pusta CameraPage
wartość musi być wyświetlana przez aplikację Xamarin.Forms . Dzieje się tak, gdy przycisk na wystąpieniu MainPage
jest naciśnięty, który z kolei wykonuje metodę OnTakePhotoButtonClicked
, jak pokazano w poniższym przykładzie kodu:
async void OnTakePhotoButtonClicked (object sender, EventArgs e)
{
await Navigation.PushAsync (new CameraPage ());
}
Ten kod po prostu przechodzi do CameraPage
elementu , na którym niestandardowe programy renderowane dostosują wygląd strony na każdej platformie.
Tworzenie modułu renderowania stron na każdej platformie
Proces tworzenia niestandardowej klasy renderera jest następujący:
- Utwórz podklasę
PageRenderer
klasy. - Zastąpi metodę
OnElementChanged
, która renderuje stronę natywną i zapisuje logikę w celu dostosowania strony. Metoda jest wywoływanaOnElementChanged
po utworzeniu odpowiedniej Xamarin.Forms kontrolki. ExportRenderer
Dodaj atrybut do klasy modułu renderowania strony, aby określić, że będzie on używany do renderowania Xamarin.Forms strony. Ten atrybut służy do rejestrowania niestandardowego modułu renderowania za pomocą Xamarin.Formspolecenia .
Uwaga
Opcjonalne jest podanie modułu renderatora stron w każdym projekcie platformy. Jeśli moduł renderowania strony nie jest zarejestrowany, zostanie użyty domyślny moduł renderowania strony.
Na poniższym diagramie przedstawiono obowiązki każdego projektu w przykładowej aplikacji wraz z relacją między nimi:
Wystąpienie CameraPage
jest renderowane przez klasy specyficzne dla CameraPageRenderer
platformy, które pochodzą z PageRenderer
klasy dla tej platformy. Spowoduje to renderowanie każdego CameraPage
wystąpienia przy użyciu kanału informacyjnego kamery na żywo, jak pokazano na poniższych zrzutach ekranu:
Klasa PageRenderer
uwidacznia metodę OnElementChanged
, która jest wywoływana podczas tworzenia strony w Xamarin.Forms celu renderowania odpowiedniej kontrolki natywnej. Ta metoda przyjmuje ElementChangedEventArgs
parametr zawierający OldElement
właściwości i NewElement
. Te właściwości reprezentują Xamarin.Forms element dołączony do modułu renderowania, a Xamarin.Forms element, do którego jest dołączony moduł renderujący . W przykładowej aplikacji OldElement
właściwość będzie i null
NewElement
właściwość będzie zawierać odwołanie do CameraPage
wystąpienia.
Zastępowana wersja OnElementChanged
metody w CameraPageRenderer
klasie to miejsce do wykonania dostosowania strony natywnej. Odwołanie do Xamarin.Forms renderowanego wystąpienia strony można uzyskać za pośrednictwem Element
właściwości .
Każda niestandardowa klasa modułu renderowania jest ozdobiona atrybutem ExportRenderer
, który rejestruje program renderujący za pomocą Xamarin.Formspolecenia . Atrybut przyjmuje dwa parametry — nazwę Xamarin.Forms typu renderowanej strony i nazwę typu niestandardowego modułu renderowania. Prefiks assembly
atrybutu określa, że atrybut ma zastosowanie do całego zestawu.
W poniższych sekcjach omówiono implementację niestandardowego modułu CameraPageRenderer
renderowania dla każdej platformy.
Tworzenie modułu renderowania stron w systemie iOS
Poniższy przykładowy kod przedstawia moduł renderowania strony dla platformy iOS:
[assembly:ExportRenderer (typeof(CameraPage), typeof(CameraPageRenderer))]
namespace CustomRenderer.iOS
{
public class CameraPageRenderer : PageRenderer
{
...
protected override void OnElementChanged (VisualElementChangedEventArgs e)
{
base.OnElementChanged (e);
if (e.OldElement != null || Element == null) {
return;
}
try {
SetupUserInterface ();
SetupEventHandlers ();
SetupLiveCameraStream ();
AuthorizeCameraUse ();
} catch (Exception ex) {
System.Diagnostics.Debug.WriteLine (@" ERROR: ", ex.Message);
}
}
...
}
}
Wywołanie metody klasy bazowej OnElementChanged
tworzy wystąpienie kontrolki systemu iOS UIViewController
. Strumień kamery na żywo jest renderowany tylko pod warunkiem, że program renderujący nie jest jeszcze dołączony do istniejącego Xamarin.Forms elementu i pod warunkiem, że wystąpienie strony istnieje, które jest renderowane przez niestandardowy moduł renderujący.
Strona jest następnie dostosowywana przez serię metod, które używają AVCapture
interfejsów API do udostępniania strumienia na żywo z aparatu i możliwości przechwytywania zdjęcia.
Tworzenie modułu renderowania stron w systemie Android
Poniższy przykładowy kod przedstawia moduł renderowania strony dla platformy Android:
[assembly: ExportRenderer(typeof(CameraPage), typeof(CameraPageRenderer))]
namespace CustomRenderer.Droid
{
public class CameraPageRenderer : PageRenderer, TextureView.ISurfaceTextureListener
{
...
public CameraPageRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
try
{
SetupUserInterface();
SetupEventHandlers();
AddView(view);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(@" ERROR: ", ex.Message);
}
}
...
}
}
Wywołanie metody klasy bazowej OnElementChanged
tworzy wystąpienie kontrolki systemu Android ViewGroup
, która jest grupą widoków. Strumień kamery na żywo jest renderowany tylko pod warunkiem, że program renderujący nie jest jeszcze dołączony do istniejącego Xamarin.Forms elementu i pod warunkiem, że wystąpienie strony istnieje, które jest renderowane przez niestandardowy moduł renderujący.
Strona jest następnie dostosowywana przez wywołanie serii metod, które używają interfejsu Camera
API do udostępniania strumienia na żywo z aparatu i możliwości przechwytywania zdjęcia, zanim AddView
metoda zostanie wywołana w celu dodania interfejsu użytkownika strumienia kamery na żywo do interfejsu ViewGroup
użytkownika . Należy pamiętać, że w systemie Android należy również zastąpić metodę OnLayout
do wykonywania operacji miary i układu w widoku.
Tworzenie modułu renderowania stron na platformie UWP
Poniższy przykład kodu przedstawia moduł renderowania strony dla platformy UWP:
[assembly: ExportRenderer(typeof(CameraPage), typeof(CameraPageRenderer))]
namespace CustomRenderer.UWP
{
public class CameraPageRenderer : PageRenderer
{
...
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
{
return;
}
try
{
...
SetupUserInterface();
SetupBasedOnStateAsync();
this.Children.Add(page);
}
...
}
protected override Size ArrangeOverride(Size finalSize)
{
page.Arrange(new Windows.Foundation.Rect(0, 0, finalSize.Width, finalSize.Height));
return finalSize;
}
...
}
}
Wywołanie metody klasy bazowej OnElementChanged
tworzy wystąpienie kontrolki FrameworkElement
, na której jest renderowana strona. Strumień kamery na żywo jest renderowany tylko pod warunkiem, że program renderujący nie jest jeszcze dołączony do istniejącego Xamarin.Forms elementu i pod warunkiem, że wystąpienie strony istnieje, które jest renderowane przez niestandardowy moduł renderujący. Następnie strona jest dostosowywana przez wywołanie serii metod, które używają interfejsu MediaCapture
API do udostępniania strumienia na żywo z aparatu i możliwość przechwytywania zdjęcia przed dodaniu dostosowanej strony do Children
kolekcji do wyświetlania.
Podczas implementowania niestandardowego modułu renderowania pochodzącego z PageRenderer
platformy UWP ArrangeOverride
należy również zaimplementować metodę w celu rozmieszczania kontrolek strony, ponieważ podstawowy moduł renderujący nie wie, co z nimi zrobić. W przeciwnym razie wyniki pustej strony. W związku z tym w tym przykładzie ArrangeOverride
metoda wywołuje metodę Arrange
w wystąpieniu Page
.
Uwaga
Ważne jest, aby zatrzymać i usunąć obiekty, które zapewniają dostęp do aparatu w aplikacji platformy UWP. Niepowodzenie tej czynności może zakłócać działanie innych aplikacji, które próbują uzyskać dostęp do aparatu urządzenia. Aby uzyskać więcej informacji, zobacz Wyświetlanie podglądu aparatu.
Podsumowanie
W tym artykule pokazano, jak utworzyć niestandardowy moduł renderujący dla ContentPage
strony, umożliwiając deweloperom zastąpienie domyślnego renderowania natywnego własnym dostosowaniem specyficznym dla platformy. Element ContentPage
jest elementem wizualnym, który wyświetla pojedynczy widok i zajmuje większość ekranu.