Menerapkan Tampilan
Xamarin.Forms kontrol antarmuka pengguna kustom harus berasal dari kelas Tampilan, yang digunakan untuk menempatkan tata letak dan kontrol di layar. Artikel ini menunjukkan cara membuat perender kustom untuk Xamarin.Forms kontrol kustom yang digunakan untuk menampilkan streaming video pratinjau dari kamera perangkat.
Setiap Xamarin.Forms tampilan memiliki perender yang menyertainya untuk setiap platform yang membuat instans kontrol asli. View
Ketika dirender oleh Xamarin.Forms aplikasi di iOS, ViewRenderer
kelas dibuat, yang pada gilirannya membuat instans kontrol asliUIView
. Pada platform Android, ViewRenderer
kelas membuat instans kontrol asli View
. Pada Platform Windows Universal (UWP), ViewRenderer
kelas membuat instans kontrol asliFrameworkElement
. Untuk informasi selengkapnya tentang kelas perender dan kontrol asli yang Xamarin.Forms mengontrol peta ke, lihat Kelas Dasar Perender dan Kontrol Asli.
Catatan
Beberapa kontrol di Android menggunakan perender cepat, yang tidak menggunakan ViewRenderer
kelas . Untuk informasi selengkapnya tentang perender cepat, lihat Xamarin.Forms Perender Cepat.
Diagram berikut mengilustrasikan hubungan antara View
kontrol asli terkait dan yang mengimplementasikannya:
Proses penyajian dapat digunakan untuk mengimplementasikan penyesuaian khusus platform dengan membuat perender kustom untuk View
di setiap platform. Proses untuk melakukan ini adalah sebagai berikut:
- BuatXamarin.Forms kontrol kustom.
- Gunakan kontrol kustom dari Xamarin.Forms.
- Buat perender kustom untuk kontrol pada setiap platform.
Setiap item sekarang akan dibahas secara bergantian, untuk mengimplementasikan perender CameraPreview
yang menampilkan streaming video pratinjau dari kamera perangkat. Mengetuk streaming video akan berhenti dan memulainya.
Membuat Kontrol Kustom
Kontrol kustom dapat dibuat dengan mensubkelas View
kelas, seperti yang ditunjukkan dalam contoh kode berikut:
public class CameraPreview : View
{
public static readonly BindableProperty CameraProperty = BindableProperty.Create (
propertyName: "Camera",
returnType: typeof(CameraOptions),
declaringType: typeof(CameraPreview),
defaultValue: CameraOptions.Rear);
public CameraOptions Camera
{
get { return (CameraOptions)GetValue (CameraProperty); }
set { SetValue (CameraProperty, value); }
}
}
CameraPreview
Kontrol kustom dibuat dalam proyek pustaka .NET Standard dan menentukan API untuk kontrol. Kontrol kustom mengekspos Camera
properti yang digunakan untuk mengontrol apakah aliran video harus ditampilkan dari kamera depan atau belakang pada perangkat. Jika nilai tidak ditentukan untuk Camera
properti saat kontrol dibuat, nilai defaultnya adalah menentukan kamera belakang.
Mengonsumsi Kontrol Kustom
CameraPreview
Kontrol kustom dapat direferensikan dalam XAML dalam proyek pustaka Standar .NET dengan mendeklarasikan namespace untuk lokasinya dan menggunakan awalan namespace pada elemen kontrol kustom. Contoh kode berikut menunjukkan bagaimana CameraPreview
kontrol kustom dapat digunakan oleh halaman XAML:
<ContentPage ...
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
...>
<StackLayout>
<Label Text="Camera Preview:" />
<local:CameraPreview Camera="Rear"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage>
local
Awalan namespace dapat diberi nama apa pun. Namun, clr-namespace
nilai dan assembly
harus cocok dengan detail kontrol kustom. Setelah namespace dinyatakan, awalan digunakan untuk mereferensikan kontrol kustom.
Contoh kode berikut menunjukkan bagaimana CameraPreview
kontrol kustom dapat dikonsumsi oleh halaman C#:
public class MainPageCS : ContentPage
{
public MainPageCS ()
{
...
Content = new StackLayout
{
Children =
{
new Label { Text = "Camera Preview:" },
new CameraPreview
{
Camera = CameraOptions.Rear,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand
}
}
};
}
}
Instans CameraPreview
kontrol kustom akan digunakan untuk menampilkan streaming video pratinjau dari kamera perangkat. Selain menentukan nilai untuk Camera
properti secara opsional, penyesuaian kontrol akan dilakukan di perender kustom.
Perender kustom sekarang dapat ditambahkan ke setiap proyek aplikasi untuk membuat kontrol pratinjau kamera khusus platform.
Membuat Perender Kustom di setiap Platform
Proses untuk membuat kelas perender kustom di iOS dan UWP adalah sebagai berikut:
- Buat subkelas
ViewRenderer<T1,T2>
kelas yang merender kontrol kustom. Argumen jenis pertama harus menjadi kontrol kustom untuk perender, dalam halCameraPreview
ini . Argumen jenis kedua harus menjadi kontrol asli yang akan mengimplementasikan kontrol kustom. - Ambil alih
OnElementChanged
metode yang merender kontrol kustom dan logika tulis untuk menyesuaikannya. Metode ini dipanggil ketika kontrol yang Xamarin.Forms sesuai dibuat. ExportRenderer
Tambahkan atribut ke kelas perender kustom untuk menentukan bahwa atribut tersebut akan digunakan untuk merender Xamarin.Forms kontrol kustom. Atribut ini digunakan untuk mendaftarkan perender kustom dengan Xamarin.Forms.
Proses untuk membuat kelas perender kustom di Android, sebagai perender cepat, adalah sebagai berikut:
- Buat subkelas kontrol Android yang merender kontrol kustom. Selain itu, tentukan bahwa subkelas akan mengimplementasikan
IVisualElementRenderer
antarmuka danIViewRenderer
. - Terapkan
IVisualElementRenderer
antarmuka danIViewRenderer
di kelas perender cepat. ExportRenderer
Tambahkan atribut ke kelas perender kustom untuk menentukan bahwa atribut tersebut akan digunakan untuk merender Xamarin.Forms kontrol kustom. Atribut ini digunakan untuk mendaftarkan perender kustom dengan Xamarin.Forms.
Catatan
Untuk sebagian besar Xamarin.Forms elemen, adalah opsional untuk menyediakan perender kustom di setiap proyek platform. Jika perender kustom tidak terdaftar, maka perender default untuk kelas dasar kontrol akan digunakan. Namun, perender kustom diperlukan di setiap proyek platform saat merender elemen Tampilan .
Diagram berikut mengilustrasikan tanggung jawab setiap proyek dalam aplikasi sampel, bersama dengan hubungan di antara mereka:
CameraPreview
Kontrol kustom dirender oleh kelas perender khusus platform, yang berasal dari ViewRenderer
kelas di iOS dan UWP, dan dari FrameLayout
kelas di Android. Ini menghasilkan setiap CameraPreview
kontrol kustom yang dirender dengan kontrol khusus platform, seperti yang ditunjukkan pada cuplikan layar berikut:
Kelas ViewRenderer
mengekspos OnElementChanged
metode , yang dipanggil ketika Xamarin.Forms kontrol kustom dibuat untuk merender kontrol asli yang sesuai. Metode ini mengambil ElementChangedEventArgs
parameter yang berisi OldElement
properti dan NewElement
. Properti ini mewakili Xamarin.Forms elemen tempat perender dilampirkan, dan Xamarin.Forms elemen yang dilampirkan oleh perender. Dalam aplikasi sampel, OldElement
properti akan menjadi null
dan NewElement
properti akan berisi referensi ke CameraPreview
instans.
Versi OnElementChanged
metode yang ditimpa, di setiap kelas perender khusus platform, adalah tempat untuk melakukan instans dan kustomisasi kontrol asli. Metode SetNativeControl
ini harus digunakan untuk membuat instans kontrol asli, dan metode ini juga akan menetapkan referensi kontrol ke Control
properti . Selain itu, referensi ke Xamarin.Forms kontrol yang sedang dirender dapat diperoleh melalui Element
properti .
Dalam beberapa keadaan, OnElementChanged
metode ini dapat dipanggil beberapa kali. Oleh karena itu, untuk mencegah kebocoran memori, perawatan harus dilakukan saat membuat instans kontrol asli baru. Pendekatan yang digunakan saat membuat instans kontrol asli baru dalam perender kustom diperlihatkan dalam contoh kode berikut:
protected override void OnElementChanged (ElementChangedEventArgs<NativeListView> e)
{
base.OnElementChanged (e);
if (e.OldElement != null)
{
// Unsubscribe from event handlers and cleanup any resources
}
if (e.NewElement != null)
{
if (Control == null)
{
// Instantiate the native control and assign it to the Control property with
// the SetNativeControl method
}
// Configure the control and subscribe to event handlers
}
}
Kontrol asli baru hanya boleh dibuat sekali, ketika Control
properti adalah null
. Selain itu, kontrol hanya boleh dibuat, dikonfigurasi, dan penanganan aktivitas berlangganan saat perender kustom dilampirkan ke elemen baru Xamarin.Forms . Demikian pula, setiap penanganan aktivitas yang berlangganan hanya boleh dihentikan langganannya ketika elemen yang dilampirkan oleh perender dilampirkan ke perubahan. Mengadopsi pendekatan ini akan membantu membuat perender kustom berkinerja yang tidak menderita kebocoran memori.
Penting
Metode SetNativeControl
hanya boleh dipanggil jika e.NewElement
bukan null
.
Setiap kelas perender kustom dihiasi dengan ExportRenderer
atribut yang mendaftarkan perender dengan Xamarin.Forms. Atribut mengambil dua parameter – nama jenis kontrol kustom yang Xamarin.Forms dirender, dan nama jenis perender kustom. assembly
Awalan ke atribut menentukan bahwa atribut berlaku untuk seluruh rakitan.
Bagian berikut membahas implementasi setiap kelas perender kustom khusus platform.
Membuat Perender Kustom di iOS
Contoh kode berikut menunjukkan perender kustom untuk platform iOS:
[assembly: ExportRenderer (typeof(CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.iOS
{
public class CameraPreviewRenderer : ViewRenderer<CameraPreview, UICameraPreview>
{
UICameraPreview uiCameraPreview;
protected override void OnElementChanged (ElementChangedEventArgs<CameraPreview> e)
{
base.OnElementChanged (e);
if (e.OldElement != null) {
// Unsubscribe
uiCameraPreview.Tapped -= OnCameraPreviewTapped;
}
if (e.NewElement != null) {
if (Control == null) {
uiCameraPreview = new UICameraPreview (e.NewElement.Camera);
SetNativeControl (uiCameraPreview);
}
// Subscribe
uiCameraPreview.Tapped += OnCameraPreviewTapped;
}
}
void OnCameraPreviewTapped (object sender, EventArgs e)
{
if (uiCameraPreview.IsPreviewing) {
uiCameraPreview.CaptureSession.StopRunning ();
uiCameraPreview.IsPreviewing = false;
} else {
uiCameraPreview.CaptureSession.StartRunning ();
uiCameraPreview.IsPreviewing = true;
}
}
...
}
}
Control
Asalkan properti adalah null
, SetNativeControl
metode ini dipanggil untuk membuat instans kontrol baru UICameraPreview
dan untuk menetapkan referensi ke Control
properti . Kontrol UICameraPreview
adalah kontrol kustom khusus platform yang menggunakan AVCapture
API untuk menyediakan aliran pratinjau dari kamera. Ini mengekspos Tapped
peristiwa yang ditangani oleh OnCameraPreviewTapped
metode untuk menghentikan dan memulai pratinjau video saat diketuk. Peristiwa Tapped
ini berlangganan ketika perender kustom dilampirkan ke elemen baru Xamarin.Forms , dan berhenti berlangganan hanya ketika elemen perender dilampirkan ke perubahan.
Membuat Custom Renderer di Android
Contoh kode berikut menunjukkan perender cepat untuk platform Android:
[assembly: ExportRenderer(typeof(CustomRenderer.CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.Droid
{
public class CameraPreviewRenderer : FrameLayout, IVisualElementRenderer, IViewRenderer
{
// ...
CameraPreview element;
VisualElementTracker visualElementTracker;
VisualElementRenderer visualElementRenderer;
FragmentManager fragmentManager;
CameraFragment cameraFragment;
FragmentManager FragmentManager => fragmentManager ??= Context.GetFragmentManager();
public event EventHandler<VisualElementChangedEventArgs> ElementChanged;
public event EventHandler<PropertyChangedEventArgs> ElementPropertyChanged;
CameraPreview Element
{
get => element;
set
{
if (element == value)
{
return;
}
var oldElement = element;
element = value;
OnElementChanged(new ElementChangedEventArgs<CameraPreview>(oldElement, element));
}
}
public CameraPreviewRenderer(Context context) : base(context)
{
visualElementRenderer = new VisualElementRenderer(this);
}
void OnElementChanged(ElementChangedEventArgs<CameraPreview> e)
{
CameraFragment newFragment = null;
if (e.OldElement != null)
{
e.OldElement.PropertyChanged -= OnElementPropertyChanged;
cameraFragment.Dispose();
}
if (e.NewElement != null)
{
this.EnsureId();
e.NewElement.PropertyChanged += OnElementPropertyChanged;
ElevationHelper.SetElevation(this, e.NewElement);
newFragment = new CameraFragment { Element = element };
}
FragmentManager.BeginTransaction()
.Replace(Id, cameraFragment = newFragment, "camera")
.Commit();
ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
}
async void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
ElementPropertyChanged?.Invoke(this, e);
switch (e.PropertyName)
{
case "Width":
await cameraFragment.RetrieveCameraDevice();
break;
}
}
// ...
}
}
Dalam contoh ini, OnElementChanged
metode membuat CameraFragment
objek, asalkan perender kustom dilampirkan ke elemen baru Xamarin.Forms . Jenisnya CameraFragment
adalah kelas kustom yang menggunakan Camera2
API untuk menyediakan aliran pratinjau dari kamera. Objek CameraFragment
dibuang ketika elemen perender Xamarin.Forms dilampirkan ke perubahan.
Membuat Perender Kustom di UWP
Contoh kode berikut menunjukkan perender kustom untuk UWP:
[assembly: ExportRenderer(typeof(CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.UWP
{
public class CameraPreviewRenderer : ViewRenderer<CameraPreview, Windows.UI.Xaml.Controls.CaptureElement>
{
...
CaptureElement _captureElement;
bool _isPreviewing;
protected override void OnElementChanged(ElementChangedEventArgs<CameraPreview> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe
Tapped -= OnCameraPreviewTapped;
...
}
if (e.NewElement != null)
{
if (Control == null)
{
...
_captureElement = new CaptureElement();
_captureElement.Stretch = Stretch.UniformToFill;
SetupCamera();
SetNativeControl(_captureElement);
}
// Subscribe
Tapped += OnCameraPreviewTapped;
}
}
async void OnCameraPreviewTapped(object sender, TappedRoutedEventArgs e)
{
if (_isPreviewing)
{
await StopPreviewAsync();
}
else
{
await StartPreviewAsync();
}
}
...
}
}
Control
Asalkan properti adalah null
, yang baru CaptureElement
dibuat dan SetupCamera
metode dipanggil, yang menggunakan MediaCapture
API untuk menyediakan streaming pratinjau dari kamera. Metode SetNativeControl
ini kemudian dipanggil untuk menetapkan referensi ke CaptureElement
instans ke Control
properti . Kontrol CaptureElement
mengekspos Tapped
peristiwa yang ditangani oleh OnCameraPreviewTapped
metode untuk menghentikan dan memulai pratinjau video saat diketuk. Peristiwa Tapped
ini berlangganan ketika perender kustom dilampirkan ke elemen baru Xamarin.Forms , dan berhenti berlangganan hanya ketika elemen perender dilampirkan ke perubahan.
Catatan
Penting untuk menghentikan dan membuang objek yang menyediakan akses ke kamera dalam aplikasi UWP. Kegagalan untuk melakukannya dapat mengganggu aplikasi lain yang mencoba mengakses kamera perangkat. Untuk informasi selengkapnya, lihat Menampilkan pratinjau kamera.
Ringkasan
Artikel ini telah menunjukkan cara membuat perender kustom untuk Xamarin.Forms kontrol kustom yang digunakan untuk menampilkan streaming video pratinjau dari kamera perangkat. Xamarin.Forms kontrol antarmuka pengguna kustom harus berasal dari View
kelas , yang digunakan untuk menempatkan tata letak dan kontrol di layar.