Büyükannenin Tariflerini Xamarin.Forms ile Kaydetme
Yayınlanan: 2022-03-10Büyükannem şimdiye kadar kimsenin tatmadığı en iyi, en kabarık, diz çökmüş çörekleri yapar. Sorun şu ki, bu çöreklere giren bir ton gizli içerik var (ve sadece aşktan bahsetmiyorum) ve bu malzemeler ve yönergelerin hepsi büyükannemin kafasında saklanıyor.
Hepimizin böyle aile tarifleri var ve muhtemelen onları unutmak yerine, bu yazıda Xamarin kullanarak iOS ve Android için bir mobil uygulama oluşturacağız. Formları kendim ve ailemin gelecek nesilleri için kurtaracak!
Yani mobil uygulama yazmakla ilgileniyorsanız ancak her platform için aynı uygulamayı tekrar tekrar yazmaya vaktiniz yoksa bu yazı tam size göre! Çilekli Pretzel Salatasından C# bilmiyorsanız endişelenmeyin; 8 yılı aşkın bir süredir Xamarin uygulamaları yazıyorum ve bu makale, kendi başınıza öğrenmeye başlamanız için size yeterli bilgiyi vermeyi amaçlayan bir Xamarin.Forms turudur.
Bu Xamarin Malzemesi Nedir?
Söylemesi eğlenceli bir kelimeden daha fazlası olan Xamarin, geliştiricilerin iOS için Swift ve XCode veya Android için Java ve Android Studio'da bulunan SDK'ları ve UI kontrollerini kullanarak yerel iOS ve Android uygulamaları oluşturmasına olanak tanır.
Aradaki fark, uygulamaların .NET Framework ve Visual Studio veya Mac için Visual Studio kullanılarak C# ile geliştirilmesidir. Bununla birlikte, sonuçta ortaya çıkan uygulamalar tamamen aynıdır. Objective-C, Swift veya Java ile yazılmış yerel uygulamalar gibi görünürler, hissederler ve davranırlar.
Kod paylaşımı söz konusu olduğunda Xamarin parlıyor. Bir geliştirici, yerel denetimleri ve SDK'ları kullanarak her platform için kullanıcı arabirimini oluşturabilir ve özelleştirebilir, ancak daha sonra platformlar arasında paylaşılan bir paylaşılan uygulama mantığı kitaplığı yazabilir.
Muazzam zaman tasarrufunun gerçekleştirilebileceği bu kod paylaşımıdır.
Ve büyükannemin pişirdiği lezzetli çörekler gibi, bir kez kod paylaşmanın tadı verildiğinde - daha fazlasını istememek elde değil - ve işte Xamarin.Forms burada devreye giriyor.
Xamarin.Formlar
Xamarin.Forms, geleneksel Xamarin geliştirme kavramını alır ve buna bir soyutlama katmanı ekler.
Xamarin.Forms, iOS ve Android için kullanıcı arabirimini ayrı ayrı geliştirmek yerine, tek bir kod tabanından yerel mobil uygulamalar yazmanıza olanak tanıyan bir UI araç takımı sunar.
Bunu şu şekilde düşünün: Düğmeye ihtiyaç duyan bir uygulamanız var. Her platformun bir düğme konsepti vardır. Uygulamanızın tüm kullanıcısının tek bir düğmeye dokunması gerektiğini bildiğiniz halde, neden kullanıcı arayüzünü birkaç kez yazmanız gerekiyor?
Bu, Xamarin.Forms'un çözdüğü sorunlardan biridir.
Bunlar için en sık kullanılan kontroller ve kullanıcı etkileşimi olaylarından oluşan bir araç takımı sağlar, bu nedenle uygulamalarımız için kullanıcı arayüzlerini yalnızca bir kez yazmamız yeterlidir. Xamarin.Forms'un sağladığı denetimlerle de sınırlı olmadığınızı belirtmekte fayda var — yine de bir Xamarin.Forms uygulamasında yalnızca tek bir platformda bulunan denetimleri kullanabilirsiniz. Ayrıca uygulama mantığını da eskisi gibi platformlar arasında paylaşabiliyoruz.
Xamarin.Forms ile geliştirilen uygulamalar için kod paylaşım istatistikleri çizelgelerin dışında olabilir. Bir konferans düzenleme uygulaması, kodunun %93'ünü iOS'ta ve %91'ini Android'de paylaşır. Uygulama açık kaynaklıdır. Koda bir göz atın.
Xamarin.Forms, kullanıcı arabirimi denetimlerinden daha fazlasını sağlar. Ayrıca bir MVVM çerçevesi, bir yayın/alt mesajlaşma hizmeti, bir animasyon API'si ve bir bağımlılık hizmeti ile diğerlerini içerir.
Ancak bugün, tarif yöneticisi uygulamamızı oluşturmak için UI özelliklerine odaklanacağız.
Yapacağımız Uygulama
Tarif yöneticisi uygulaması basit bir kullanıcı arayüzüne sahip olacaktır. Mutfakta çalışacağız, bu yüzden kullanımı kolay olmalı!
3 ekrandan oluşacaktır . İlki, uygulamada şu anda yüklü olan tüm tariflerin bir listesini gösterecektir.
Ardından, bu tariflerden birine dokunarak ayrıntılarını ikinci bir ekranda görebileceksiniz:
Oradan, üçüncü ekranda tarifte değişiklik yapmak için bir düzenle düğmesine dokunabilirsiniz:
Bu ekrana tarif listesi ekranından ekle butonuna basarak da ulaşabilirsiniz.
Geliştirme Ortamı
Xamarin uygulamaları, Windows'ta Visual Studio veya Mac'te Mac için Visual Studio kullanılarak C# ve .NET ile oluşturulmuştur, ancak iOS veya Android SDK'larının ve araçlarının da yüklü olması gerekir. Her şeyi doğru sırayla yüklemek biraz sorun olabilir, ancak Visual Studio yükleyicileri yalnızca IDE'nin yüklenmesini ve aynı zamanda platform araçlarını da dikkate alacaktır.
iOS uygulamaları oluşturmak için her zaman bir Mac gerekli olsa da, Xamarin ile bu uygulamaları Windows üzerinde Visual Studio'dan geliştirebilir ve hatalarını ayıklayabilirsiniz! Bu nedenle, Windows sıkışıklığınız ise, ortamlarınızı tamamen değiştirmenize gerek yoktur.
Şimdi Xamarin.Forms'un bazı aile tariflerini tek bir kod tabanından kaydetmemize nasıl yardımcı olabileceğini görelim!
Tarif Listesi Sayfası: Kullanıcı Arayüzünü Düzenleme
Tarif kaydetme uygulamamız için kullanıcı arayüzünü nasıl düzenleyeceğimizden bahsederek başlayalım!
Genel olarak Xamarin.Forms'daki her ekran 3 öğeden oluşur. Bir Page
. Layout
adı verilen en az bir öğe. Ve en az bir Control
.
Sayfa
Sayfa, ekranda görüntülenen her şeyi aynı anda barındıran şeydir. Page
aynı zamanda bir uygulama içinde gezinmenin merkezinde yer alır.
Xamarin.Forms'a Navigation Service aracılığıyla hangi Page
görüntüleneceğini söyleriz. Bu hizmet daha sonra herhangi bir sayfayı işletim sistemi için uygun ve yerel bir şekilde görüntülemeye özen gösterecektir.
Başka bir deyişle, ekranlar arasında gezinme kodu da soyutlandı!
Son olarak, bunu yapmanın tek yolu olmasa da, Sayfamın kullanıcı arayüzünü Page
kodluyorum. (Diğer yol C# kullanmaktır.) XAML, bir sayfanın nasıl göründüğünü açıklayan bir biçimlendirme dilidir. Ve şimdilik, HTML'ye biraz benzer olduğunu söylemek yeterli.
Tasarım
Bir sayfadaki tüm kontroller, Düzen adı verilen bir şey tarafından düzenlenir.
Bir sayfaya bir veya daha fazla düzen eklenebilir.
Formlarda birkaç farklı Düzen türü vardır. En yaygın olanlardan bazıları Yığın, Mutlak, Göreli, Izgara, Kaydırma ve Esnek düzenleri içerir.
Kontroller
Sonra nihayet kontroller var. Bunlar, kullanıcının etkileşimde bulunduğu uygulamanızın widget'larıdır.
Formlar, ne tür bir uygulama oluşturuyor olursanız olun kullanılacak birçok kontrolle birlikte gelir. Etiketler, düğmeler, giriş kutuları, resimler ve tabii ki liste görünümleri gibi şeyler.
Bir ekrana denetim eklerken, onu bir düzene eklersiniz. Kontrolün tam olarak ekranda nerede görünmesi gerektiğini anlamaya özen gösteren düzendir.
Sırasıyla iOS ve Android'de aşağıdaki ekranları oluşturmak için:
Bu XAML'yi kullandım:
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="https://xamarin.com/schemas/2014/forms" xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml" x:Class="SmashingRecipe.RecipeListPage" Title="Recipes"> <ContentPage.Content> <StackLayout> <ListView x:Name="recipesList"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding Name}"/> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </ContentPage.Content> <ContentPage.ToolbarItems> <ToolbarItem Text="Add" /> </ContentPage.ToolbarItems> </ContentPage>
Burada birkaç önemli şey oluyor.
Birincisi <StackLayout>
. Bu, Forms'a bir yığında takip eden tüm denetimleri düzenlemesini söylüyor.
Düzende yalnızca tek bir kontrol olur ve bu bir <ListView>
'dir ve daha sonra başvurabilmemiz için ona bir ad vereceğiz.
Ardından, peşinde olduğumuz şeye ulaşmadan önce ListView
biraz standart bir tören var: <TextCell>
. Bu, Forms'a listenin her hücresinde basit metin görüntülemesini söylüyor.
<TextCell>
'e göstermesini istediğimiz metni Data Binding adlı bir teknikle söyleriz. Sözdizimi Text="{Binding Name}"
gibi görünüyor. Name
bir Recipe
sınıfının bir özelliği olduğu yerde… iyi, Tarifler.
Peki tarifler listeye nasıl eklenir?
Her XAML dosyasıyla birlikte bir "arka plan kodu" dosyası vardır. Bu arka plan kodu, kullanıcı etkileşimi olaylarını işlemek veya kurulum gerçekleştirmek veya başka uygulama mantığı yapmak gibi şeyler yapmamıza olanak tanır.
OnAppearing
adlı her Page
geçersiz kılınabilecek bir işlev var - ki tahmin ettiğiniz gibi - Page
göründüğünde çağrılır.
protected override void OnAppearing() { base.OnAppearing(); recipesList.ItemsSource = null; recipesList.ItemsSource = App.AllRecipes; }
recipesList.ItemsSource = AllRecipes;
Bu, ListView
söylüyor - “Hey! Tüm verileriniz numaralandırılabilir App.AllRecipes
(uygulama çapında bir değişken) içinde bulunur ve bağlanmak için alt nesnesinin özelliklerinden herhangi birini kullanabilirsiniz!”.
Bir yemek tarifleri listesi gayet iyi - ama önce tarifin ayrıntılarını görmeden hiçbir şey pişiremezsiniz - ve bundan sonra bununla ilgileneceğiz.
Olay işleme
Kullanıcı dokunuşlarına cevap vermeden uygulamamız kulağa lezzetli gelen tarifler listesinden başka bir şey değil. Kulağa hoş geliyorlar, ama onları nasıl pişireceklerini bilmeden pek bir faydası yok!
Tarifi nasıl yapacağımızı görebilmemiz için ListView
her hücrenin dokunuşlara yanıt vermesini sağlayalım!
RecipeListPage
arka plan kod dosyasında, kullanıcı etkileşimi olaylarını dinlemek ve bunlara tepki vermek için kontrollere olay işleyicileri ekleyebiliriz.
Liste görünümünde dokunma olaylarını işlemek ve ardından:
recipesList.ItemSelected += async (sender, eventArgs) => { if (eventArgs.SelectedItem != null) { var detailPage = new RecipeDetailPage(eventArgs.SelectedItem as Recipe); await Navigation.PushAsync(detailPage); recipesList.SelectedItem = null; } };
Orada güzel şeyler oluyor.
Birisi bir satır seçtiğinde, ItemSelected
ListView
üzerinde tetiklenir.
İşleyiciye iletilen argümanlardan eventArgs
nesnesi, daha önce ListView
bağlı olan her şey olan bir SelectedItem
özelliğine sahiptir.
Bizim durumumuzda bu, Recipe
sınıfıdır. (Yani nesneyi ana kaynakta aramak zorunda değiliz - bize iletilir.)
Tarif Detay Sayfası
Tabii ki, bize her tarifin nasıl yapılacağına dair gizli malzemeleri ve talimatları gösteren bir sayfa var, ama o sayfa nasıl görüntüleniyor?
await Navigation.PushAsync(detailPage);
yukarıdan çizgi. Navigation
nesnesi, sayfa geçişlerini her platform için yerel bir biçimde işleyen platformdan bağımsız bir nesnedir.
Şimdi tarif detayları sayfasına bir göz atalım:
Bu sayfa da XAML ile oluşturulmuştur. Bununla birlikte, kullanılan Layout
(FlexLayout), CSS Flexbox'tan ilham aldığı için oldukça havalı.
<ContentPage.Content> <ScrollView> <FlexLayout AlignItems="Start" AlignContent="Start" Wrap="Wrap"> <Image Source="buns.png" FlexLayout.Basis="100%" /> <Label Text="{Binding Name}" HorizontalTextAlignment="Center" TextColor="#01487E" FontAttributes="Bold" FontSize="Large" Margin="10, 10" /> <BoxView FlexLayout.Basis="100%" HeightRequest="0" /> <Label Text="Ingredients" FontAttributes="Bold" FontSize="Medium" TextColor="#EE3F60" Margin="10,10" HorizontalOptions="FillAndExpand" /> <BoxView FlexLayout.Basis="100%" HeightRequest="0" /> <Label Text="{Binding Ingredients}" Margin="10,10" FontSize="Small" /> <BoxView FlexLayout.Basis="100%" HeightRequest="0" /> <Label Text="Directions" FontAttributes="Bold" FontSize="Medium" TextColor="#EE3F60" Margin="10,10" HorizontalOptions="FillAndExpand" /> <BoxView FlexLayout.Basis="100%" HeightRequest="0" /> <Label Text="{Binding Directions}" Margin="10,10" FontSize="Small" /> </FlexLayout> </ScrollView> </ContentPage.Content>
FlexLayout
, kontrollerini ya satırlar ya da sütunlar halinde düzenler. En büyük fayda, bir kontrolü yerleştirmek için ekranda ne kadar yer kaldığını otomatik olarak algılayabilmesi ve yeterli değilse, otomatik olarak yerleştirmek için yeni bir satır veya sütun oluşturabilmesidir!
Bu, mobil geliştirmede bol miktarda bulunan çeşitli ekran boyutlarıyla uğraşırken büyük ölçüde yardımcı olur.
FlexLayout
, ayrıntılar ekranının iyi görünmesini sağlamamıza yardımcı olurken, yine de bu tarifleri düzenlememiz gerekiyor, değil mi?
Muhtemelen şunu fark etmişsinizdir:
<ToolbarItem Text="Edit" Clicked="Edit_Clicked" />
Bu satır, uygulamanın araç çubuğuna bir düğme koymaktan sorumludur. Clicked="Edit_Clicked"
, düğmeye tıklandığında, o ismin bir işlevi için arkasındaki koda bakmasını ve ardından kodunu çalıştırmasını söyler.
Bu durumda, Reçete Düzenleme Sayfasını başlatmak ve bunu daha önce bahsedilen Navigation
nesnesini kullanarak navigasyon yığınımıza itmek olacaktır.
Tarif Düzenleme Sayfası
Tariflerin listesini içeren bir sayfa: kontrol edin! Tarifleri yapmak için tüm detayları içeren bir sayfa: kontrol edin! Şimdi geriye kalan tek şey, biz büyükannenin sihrini yaparken bir tarifi girmek veya değiştirmek için kullandığımız sayfayı oluşturmak!
İlk önce ekranlara bakın:
Ve şimdi kod:
<ContentPage.Content> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <TableView Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Intent="Form" HasUnevenRows="true"> <TableSection Title="General"> <EntryCell x:Name="recipeNameCell" Label="Name" /> </TableSection> <TableSection Title="Ingredients"> <ViewCell> <StackLayout Padding="15"> <Editor x:Name="ingredientsCell" /> </StackLayout> </ViewCell> </TableSection> <TableSection Title="Directions"> <ViewCell> <StackLayout Padding="15"> <Editor x:Name="directionsCell" /> </StackLayout> </ViewCell> </TableSection> </TableView> <Button Text="Save" Grid.Row="1" Grid.Column="0" BackgroundColor="#EE3F60" TextColor="White" x:Name="saveButton" /> <Button Text="Cancel" Grid.Row="1" Grid.Column="1" BackgroundColor="#4CC7F2" TextColor="White" x:Name="cancelButton" /> </Grid> </ContentPage.Content>
Burada biraz daha kod var ve bunun nedeni, her şeyin 2 Boyutlu bir modelde nasıl düzenleneceğini belirtmek için Grid
düzenini kullanmam.
Ayrıca burada veri bağlamadığına da dikkat edin. Çünkü sadece dosyanın arkasındaki koddan kontrollerin nasıl doldurulacağına dair bir örnek vermek istedim:
void InitializePage() { Title = TheRecipe.Name ?? "New Recipe"; recipeNameCell.Text = TheRecipe.Name; ingredientsCell.Text = TheRecipe.Ingredients; directionsCell.Text = TheRecipe.Directions; saveButton.Clicked += async (sender, args) => { SaveRecipe(); await CloseWindow(); }; cancelButton.Clicked += async (sender, args) => { await CloseWindow(); }; }
Şu TheRecipe
özelliğini görüyor musunuz? Sayfa düzeyidir, belirli bir tarif için tüm verileri tutar ve sayfanın yapıcısında ayarlanır.
İkinci olarak, saveButton
ve cancelButton
için Clicked
olay işleyicileri tamamen .NET-ified'dir (ve evet, kendi sözlerimi oldukça sık oluşturuyorum.)
.NET ile uyumlu olduklarını söylüyorum çünkü bu olayı ele alacak sözdizimi Java'ya veya Objective-C'ye özgü değil. Uygulama Android veya iOS üzerinde çalıştığında, davranış tam olarak bir Android Click veya bir iOS TouchUpInside gibi olacaktır.
Ve görebileceğiniz gibi, bu tıklama olay işleyicilerinin her biri, ya tarifi kaydeden ve sayfayı kapatan ya da sadece sayfayı kapatan uygun işlevleri çağırıyor.
İşte burada - tarifleri şu andan itibaren zamanın sonuna kadar kaydetmek için kullanıcı arayüzüne sahibiz!
CSS Ne?!? Veya Uygulamayı Güzelleştirmek
En iyisini sona saklıyoruz: Xamarin.Forms 3.0 bize - diğer şeylerin yanı sıra - CSS kullanarak kontrollere stil verme yeteneği veriyor!
Xamarin.Forms CSS, web geliştirmeden alışık olabileceğiniz %100 değildir. Ancak, CSS'ye aşina olan herkesin kendini evinde hissedeceği kadar yakındır. Tıpkı benim büyükannemdeki gibi!
Öyleyse, Tarif Ayrıntıları sayfasını alıp yeniden düzenleyelim, böylece görsel öğeleri ayarlamak için her şeyi doğrudan XAML'de satır içi olarak ayarlamak yerine Basamaklı Stil Sayfalarını kullanır.
İlk adım, CSS belgesini oluşturmaktır! Bu durumda aşağıdaki gibi görünecektir:
.flexContent { align-items: flex-start; align-content: flex-start; flex-wrap: wrap; } image { flex-basis: 100%; } .spacer { flex-basis: 100%; height: 0; } .foodHeader { font-size: large; font-weight: bold; color: #01487E; margin: 10 10; } .dataLabel { font-size: medium; font-weight: bold; color: #EE3F60; margin: 10 10; } .data { font-size: small; margin: 10 10; }
Çoğunlukla, CSS'ye benziyor. Orada sınıflar var. Sınıf türü için tek bir seçici vardır, Image
. Ve sonra bir grup mülk belirleyici.
flex-wrap
veya flex-basis
gibi bu özellik ayarlayıcılardan bazıları Xamarin.Forms'a özeldir. İleride, ekip standart uygulamaları takip etmek için xf-
ile önek koyacaktır.
Sıradaki, onu XAML kontrollerine uygulamak olacak.
<ContentPage.Resources> <StyleSheet Source="../Styles/RecipeDetailStyle.css" /> </ContentPage.Resources> <ContentPage.Content> <ScrollView> <FlexLayout StyleClass="flexContent"> <Image Source="buns.png" /> <Label Text="{Binding Name}" StyleClass="foodHeader" /> <BoxView StyleClass="spacer" /> <Label Text="Ingredients" StyleClass="dataLabel" HorizontalOptions="FillAndExpand" /> <BoxView StyleClass="spacer" /> <Label Text="{Binding Ingredients}" StyleClass="data" /> <BoxView StyleClass="spacer" /> <Label Text="Directions" StyleClass="dataLabel" HorizontalOptions="FillAndExpand" /> <BoxView StyleClass="spacer" /> <Label Text="{Binding Directions}" StyleClass="data" /> </FlexLayout> </ScrollView> </ContentPage.Content>
İşte daha önce nasıl göründüğü.
Xamarin.Forms'da, CSS belgesine başvurmak için bir <StyleSheet Source="YOUR DOC PATH" />
ekleyin. Ardından, StyleClass
özelliği aracılığıyla her kontroldeki sınıflara başvurabilirsiniz.
Kesinlikle XAML'yi temizler ve kontrolün amacını da daha net hale getirir. Örneğin, şimdi bu <BoxView StyleClass="spacer" />
ne yaptığı oldukça açık!
Ve Image
, bir Image
olduğu ve seçiciyi CSS'de tanımladığımız yol olduğu için kendi stilini alır.
Emin olmak gerekirse, Xamarin.Forms'daki CSS, web kuzeni kadar tam olarak uygulanmadı, ancak yine de oldukça havalı. Seçicileriniz, sınıflarınız var, özellikleri ayarlayabilirsiniz ve tabii ki tüm bu basamaklı şey oluyor!
Özet
Üç ekran, iki platform, bir makale ve kaydedilmiş sonsuz tarif! Ve başka ne biliyor musun? Xamarin.Forms ile Android ve iOS'tan daha fazlası için uygulamalar oluşturabilirsiniz. UWP, macOS ve hatta Samsung Tizen platformları oluşturabilirsiniz!
Xamarin.Forms, kullanıcı arabirimini bir kez yazarak ve kullanıcı arabiriminin ana platformlarda yerel olarak oluşturulmasını sağlayarak uygulamalar oluşturmanıza olanak tanıyan bir kullanıcı arabirimi araç takımıdır.
Bunu, platformlarda en sık kullanılan kontrollere yönelik bir soyutlama olan bir SDK sağlayarak yapar. UI iyiliğine ek olarak, Xamarin.Forms ayrıca tam özellikli bir MVVM çerçevesi, bir yayın/alt mesajlaşma hizmeti, bir animasyon API'si ve bir bağımlılık hizmeti sunar.
Xamarin.Forms ayrıca size geleneksel Xamarin geliştirmenin sağladığı tüm kod avantajlarını sağlar. Herhangi bir uygulama mantığı tüm platformlarda paylaşılır. Ve tüm uygulamalarınızı tek bir dil kullanarak tek bir IDE ile geliştirebilirsiniz - bu oldukça havalı!
Bir sonraki nereye? Kendiniz denemek için bu Xamarin.Forms uygulamasının kaynak kodunu indirin. Ardından, tarayıcınız içinde bir uygulama oluşturma yeteneği de dahil olmak üzere Xamarin.Forms hakkında daha fazla bilgi edinmek için bu çevrimiçi eğiticiye göz atın!