Sdílet prostřednictvím


Přizpůsobení prvku ContentPage

ContentPage je vizuální prvek, který zobrazuje jedno zobrazení a zabírá většinu obrazovky. Tento článek ukazuje, jak vytvořit vlastní renderer pro stránku ContentPage, což vývojářům umožňuje přepsat výchozí nativní vykreslování vlastním vlastním přizpůsobením specifické pro platformu.

Každý Xamarin.Forms ovládací prvek má doprovodný renderer pro každou platformu, která vytvoří instanci nativního ovládacího prvku. ContentPage Při vykreslení Xamarin.Forms aplikací se v iOSu PageRenderer vytvoří instance třídy, která následně vytvoří instanci nativního UIViewController ovládacího prvku. Na platformě Android třída PageRenderer vytvoří ViewGroup instanci ovládacího prvku. Na Univerzální platforma Windows (UPW) třída PageRenderer vytvoří FrameworkElement instanci ovládacího prvku. Další informace o rendereru a nativních tříd ovládacích prvcích, které Xamarin.Forms řídí mapování, naleznete v tématu Renderer Základní třídy a nativní ovládací prvky.

Následující diagram znázorňuje vztah mezi ContentPage a odpovídajícími nativními ovládacími prvky, které ho implementují:

Vztah mezi třídou ContentPage a implementací nativních ovládacích prvků

Proces vykreslování můžete využít k implementaci přizpůsobení specifických pro platformu vytvořením vlastního rendereru pro každou platformu ContentPage . Postup je následující:

  1. Vytvořte Xamarin.Forms stránku.
  2. Využití stránky z Xamarin.Forms.
  3. Vytvořte vlastní renderer pro stránku na každé platformě.

Každá položka se teď bude probírat a implementovat CameraPage tak živý kanál fotoaparátu a možnost zachytit fotku.

Xamarin.Forms Vytvoření stránky

Do sdíleného Xamarin.Forms projektu lze přidat nealterovaný ContentPage objekt, jak je znázorněno v následujícím příkladu kódu 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>

Podobně by měl soubor kódu pro soubor, který je za kódem ContentPage , zůstat nezměněný, jak je znázorněno v následujícím příkladu kódu:

public partial class CameraPage : ContentPage
{
    public CameraPage ()
    {
        // A custom renderer is used to display the camera UI
        InitializeComponent ();
    }
}

Následující příklad kódu ukazuje, jak lze stránku vytvořit v jazyce C#:

public class CameraPageCS : ContentPage
{
    public CameraPageCS ()
    {
    }
}

Instance bude použita k zobrazení živého CameraPage kanálu kamery na každé platformě. Přizpůsobení ovládacího prvku se provede ve vlastním rendereru, takže ve CameraPage třídě není nutná žádná další implementace.

Xamarin.Forms Využívání stránky

Aplikace musí zobrazit prázdnou CameraPage Xamarin.Forms . K tomu dochází při klepnutí na tlačítko na MainPage instanci, které následně spustí metodu OnTakePhotoButtonClicked , jak je znázorněno v následujícím příkladu kódu:

async void OnTakePhotoButtonClicked (object sender, EventArgs e)
{
    await Navigation.PushAsync (new CameraPage ());
}

Tento kód jednoduše přejde na CameraPage, na kterém vlastní renderery přizpůsobí vzhled stránky na každé platformě.

Vytvoření rendereru stránky na jednotlivých platformách

Proces vytvoření vlastní třídy rendereru je následující:

  1. Vytvořte podtřídu PageRenderer třídy.
  2. Přepište metodu OnElementChanged , která vykreslí nativní stránku a logiku zápisu pro přizpůsobení stránky. Metoda OnElementChanged je volána při vytvoření odpovídajícího Xamarin.Forms ovládacího prvku.
  3. ExportRenderer Přidejte atribut do třídy vykreslovacího modulu stránky a určete, že se použije k vykreslení Xamarin.Forms stránky. Tento atribut se používá k registraci vlastního rendereru v Xamarin.Forms.

Poznámka:

V každém projektu platformy je volitelné zadat vykreslovací modul stránky. Pokud není vykreslení stránky zaregistrované, použije se výchozí vykreslovací modul pro stránku.

Následující diagram znázorňuje zodpovědnosti jednotlivých projektů v ukázkové aplikaci spolu s vztahem mezi nimi:

Odpovědnosti vlastního vykreslovacího projektu aplikace CameraPage

Instance CameraPage je vykreslena třídami specifickými pro CameraPageRenderer platformu, které jsou odvozeny od PageRenderer třídy pro danou platformu. Výsledkem je vykreslení každé CameraPage instance s živým kanálem fotoaparátu, jak je znázorněno na následujících snímcích obrazovky:

CameraPage na jednotlivých platformách

PageRenderer Třída zveřejňuje metoduOnElementChanged, která je volána při Xamarin.Forms vytvoření stránky pro vykreslení odpovídajícího nativního ovládacího prvku. Tato metoda přebírá ElementChangedEventArgs parametr, který obsahuje OldElement a NewElement vlastnosti. Tyto vlastnosti představují Xamarin.Forms prvek, ke kterému byl renderer připojen, a Xamarin.Forms prvek, ke kterému je renderer připojen, v uvedeném pořadí. V ukázkové aplikaci OldElement bude vlastnost a NewElement vlastnost bude obsahovat odkaz na CameraPage null instanci.

Přepsáná verze OnElementChanged metody ve CameraPageRenderer třídě je místo pro provedení přizpůsobení nativní stránky. Odkaz na Xamarin.Forms instanci stránky, která se vykresluje, lze získat prostřednictvím Element vlastnosti.

Každá vlastní třída rendereru je zdobena ExportRenderer atributem, který registruje renderer s Xamarin.Forms. Atribut má dva parametry – název Xamarin.Forms typu vykreslené stránky a název typu vlastního rendereru. Předpona assembly atributu určuje, že atribut se vztahuje na celé sestavení.

Následující části popisuje implementaci vlastního rendereru CameraPageRenderer pro každou platformu.

Vytvoření rendereru stránky v iOSu

Následující příklad kódu ukazuje renderer stránky pro platformu 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);
            }
        }
        ...
    }
}

Volání metody základní třídy OnElementChanged vytvoří instanci ovládacího prvku iOS UIViewController . Stream živé kamery se vykresluje pouze za předpokladu, že renderer ještě není připojený k existujícímu Xamarin.Forms prvku, a za předpokladu, že existuje instance stránky, kterou vykresluje vlastní renderer.

Stránka se pak přizpůsobí řadou metod, které pomocí AVCapture rozhraní API poskytují živý stream z fotoaparátu a schopnost zachytit fotku.

Vytvoření rendereru stránky v Androidu

Následující příklad kódu ukazuje renderer stránky pro platformu 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);
            }
        }
        ...
    }
}

Volání metody základní třídy OnElementChanged vytvoří instanci ovládacího prvku Android ViewGroup , což je skupina zobrazení. Stream živé kamery se vykresluje pouze za předpokladu, že renderer ještě není připojený k existujícímu Xamarin.Forms prvku, a za předpokladu, že existuje instance stránky, kterou vykresluje vlastní renderer.

Stránka se pak přizpůsobí vyvoláním řady metod, které používají Camera rozhraní API k poskytování živého streamu z fotoaparátu a schopnost zachytit fotku před AddView vyvoláním metody přidání uživatelského rozhraní živého streamu fotoaparátu do ViewGrouprozhraní . Všimněte si, že v Androidu je také nutné přepsat metodu OnLayout pro provádění operací měření a rozložení v zobrazení.

Vytvoření rendereru stránky v UPW

Následující příklad kódu ukazuje vykreslovací modul stránky pro UPW:

[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;
        }
        ...
    }
}

Volání metody základní třídy OnElementChanged vytvoří FrameworkElement instanci ovládacího prvku, na kterém je stránka vykreslena. Stream živé kamery se vykresluje pouze za předpokladu, že renderer ještě není připojený k existujícímu Xamarin.Forms prvku, a za předpokladu, že existuje instance stránky, kterou vykresluje vlastní renderer. Stránka se pak přizpůsobí vyvoláním řady metod, které používají MediaCapture rozhraní API k poskytnutí živého streamu z fotoaparátu a možnosti zachytit fotku před přidáním přizpůsobené stránky do Children kolekce pro zobrazení.

Při implementaci vlastního rendereru, který je odvozen z PageRenderer UPW, ArrangeOverride by se měla také implementovat metoda pro uspořádání ovládacích prvků stránky, protože základní renderer neví, co s nimi dělat. V opačném případě se zobrazí prázdné výsledky stránky. Proto v tomto příkladu ArrangeOverride metoda volá metodu Arrange v Page instanci.

Poznámka:

Je důležité zastavit a odstranit objekty, které poskytují přístup ke kameře v aplikaci pro UPW. Pokud to neuděláte, může kolidovat s jinými aplikacemi, které se pokusí o přístup ke kameře zařízení. Další informace najdete v tématu Zobrazení náhledu fotoaparátu.

Shrnutí

Tento článek ukazuje, jak vytvořit vlastní vykreslovací modul pro ContentPage stránku, který vývojářům umožňuje přepsat výchozí nativní vykreslování vlastními vlastními přizpůsobeními pro konkrétní platformu. A ContentPage je vizuální prvek, který zobrazuje jedno zobrazení a zabírá většinu obrazovky.