Xamarin.Forms를 사용하여 할머니의 요리법 저장
게시 됨: 2022-03-10우리 할머니는 누구라도 맛본 적이 없는 최고의, 가장 푹신한, 무릎이 약한 만두를 만드십니다. 문제는 그 빵에 들어가는 비밀 재료의 톤이 있고 (그리고 나는 단지 사랑을 말하는 것이 아닙니다) 그 재료와 지시 사항이 모두 할머니의 머리에 저장되어 있다는 것입니다.
우리 모두는 이와 같은 가족 레시피를 가지고 있으며 이를 잊어버리는 대신 Xamarin.Forms를 사용하여 나와 내 가족의 미래 세대를 위해 저장할 수 있는 iOS 및 Android용 모바일 앱을 만들 것입니다.
따라서 모바일 애플리케이션 작성에 관심이 있지만 각 플랫폼에 대해 동일한 앱을 계속해서 작성할 시간이 없다면 이 기사가 적합합니다! Strawberry Pretzel Salad에서 C#을 몰라도 걱정하지 마십시오. 저는 8년 넘게 Xamarin 앱을 작성해 왔으며, 이 문서는 스스로 학습을 시작하기에 충분한 정보를 제공하기 위한 Xamarin.Forms 둘러보기입니다.
이 Xamarin 항목은 무엇입니까?
Xamarin을 사용하면 iOS용 Swift 및 XCode 또는 Android용 Java 및 Android Studio에서 사용할 수 있는 것과 똑같은 SDK 및 UI 컨트롤을 사용하여 개발자가 기본 iOS 및 Android 애플리케이션을 만들 수 있습니다.
차이점은 앱이 .NET Framework 및 Visual Studio 또는 Mac용 Visual Studio를 사용하여 C#으로 개발된다는 것입니다. 그러나 결과적으로 앱은 완전히 동일합니다. 그들은 Objective-C, Swift 또는 Java로 작성된 기본 앱처럼 보이고, 느끼고, 작동합니다.
Xamarin은 코드 공유와 관련하여 빛을 발합니다. 개발자는 네이티브 컨트롤과 SDK를 사용하여 각 플랫폼에 대한 UI를 만들고 맞춤설정할 수 있지만 플랫폼 간에 공유되는 공유 앱 로직 라이브러리를 작성할 수 있습니다.
엄청난 시간 절약을 실현할 수 있는 것은 바로 이 코드 공유입니다.
그리고 할머니가 굽는 맛있는 만두처럼, 코드 공유의 맛을 알게 되면 더 이상 갈망하지 않기가 어렵습니다. 바로 여기에서 Xamarin.Forms가 등장합니다.
Xamarin.Forms
Xamarin.Forms는 전통적인 Xamarin 개발의 개념을 취하고 여기에 추상화 계층을 추가합니다.
iOS 및 Android용 사용자 인터페이스를 별도로 개발하는 대신 Xamarin.Forms는 단일 코드 기반에서 기본 모바일 앱을 작성할 수 있는 UI 도구 키트를 도입합니다.
다음과 같이 생각하십시오. 버튼이 필요한 앱이 있습니다. 각 플랫폼에는 버튼의 개념이 있습니다. 앱 사용자가 버튼을 탭하기만 하면 된다는 것을 알면서도 사용자 인터페이스를 여러 번 작성해야 하는 이유는 무엇입니까?
이것이 Xamarin.Forms가 해결하는 문제 중 하나입니다.
가장 일반적으로 사용되는 컨트롤 및 사용자 상호 작용 이벤트의 툴킷을 제공하므로 앱에 대한 사용자 인터페이스를 한 번만 작성하면 됩니다. Xamarin.Forms가 제공하는 컨트롤로 제한되지는 않지만 Xamarin.Forms 앱 내의 단일 플랫폼에서만 찾을 수 있는 컨트롤을 계속 사용할 수 있습니다. 또한 이전과 같이 플랫폼 간에 애플리케이션 로직을 공유할 수 있습니다.
Xamarin.Forms로 개발된 앱의 코드 공유 통계는 차트에서 벗어날 수 있습니다. 회의 구성 앱은 코드의 93%가 iOS에서 공유되고 91%가 Android에서 공유됩니다. 앱은 오픈 소스입니다. 코드를 살펴보십시오.
Xamarin.Forms는 UI 컨트롤 이상의 기능을 제공합니다. 또한 MVVM 프레임워크, 게시/구독 메시징 서비스, 애니메이션 API, 종속성 서비스 및 기타 기능을 포함합니다.
하지만 오늘은 레시피 관리자 앱을 빌드하기 위한 UI 기능에 중점을 둘 것입니다.
우리가 만들 앱
레시피 관리자 앱에는 간단한 사용자 인터페이스가 있습니다. 우리는 부엌에서 일할 것이므로 사용하기 쉬워야 합니다!
3개의 화면으로 구성됩니다 . 첫 번째는 현재 앱에 로드된 모든 레시피 목록을 표시합니다.
그런 다음 해당 레시피 중 하나를 탭하면 두 번째 화면에서 세부 정보를 볼 수 있습니다.
거기에서 편집 버튼을 눌러 세 번째 화면에서 레시피를 변경할 수 있습니다.
레시피 목록 화면에서 추가 버튼을 눌러 이 화면으로 이동할 수도 있습니다.
개발 환경
Xamarin 앱은 Windows의 Visual Studio 또는 Mac의 Mac용 Visual Studio를 사용하여 C# 및 .NET으로 빌드되지만 iOS 또는 Android SDK와 도구도 설치해야 합니다. 모든 것을 올바른 순서로 설치하는 것은 약간의 문제가 될 수 있지만 Visual Studio 설치 프로그램은 IDE를 설치하는 것뿐만 아니라 플랫폼 도구도 고려합니다.
iOS 앱을 빌드하려면 항상 Mac이 필요하지만 Xamarin을 사용하면 Windows의 Visual Studio에서 이러한 앱을 계속 개발하고 디버그할 수 있습니다! 따라서 Windows가 문제인 경우 환경을 완전히 변경할 필요가 없습니다.
이제 Xamarin.Forms가 하나의 코드 기반에서 일부 가족 레시피를 저장하는 데 어떻게 도움이 되는지 봅시다!
레시피 목록 페이지: UI 레이아웃
레시피 저장 앱의 UI를 레이아웃하는 방법에 대해 이야기하는 것으로 시작하겠습니다!
전체적으로 Xamarin.Forms의 각 화면은 3가지 요소로 구성됩니다. Page
. Layout
이라는 하나 이상의 요소. 그리고 적어도 하나의 Control
.
그 페이지
페이지는 한 번에 화면에 표시되는 모든 것을 호스팅하는 것입니다. Page
는 앱 내 탐색의 중심이기도 합니다.
탐색 서비스 를 통해 표시할 Page
를 Xamarin.Forms에 알려줍니다. 그런 다음 해당 서비스는 운영 체제에 적절하고 고유한 방식으로 페이지를 표시하는 작업을 처리합니다.
즉, 화면 사이를 탐색하는 코드도 추상화되었습니다!
마지막으로, 이 작업을 수행하는 유일한 방법은 아니지만 XAML에서 내 Page
의 UI를 코딩합니다. (다른 방법은 C#을 사용하는 것입니다.) XAML은 페이지의 모양을 설명하는 마크업 언어입니다. 그리고 지금은 HTML과 일종의 유사하다고 말할 수 있습니다.
배치
페이지의 모든 컨트롤은 레이아웃이라는 항목에 의해 정렬됩니다.
하나 이상의 레이아웃을 페이지에 추가할 수 있습니다.
Forms에는 여러 유형의 레이아웃이 있습니다. 가장 일반적인 레이아웃에는 Stack, Absolute, Relative, Grid, Scroll 및 Flex 레이아웃이 있습니다.
컨트롤
그런 다음 마지막으로 컨트롤이 있습니다. 사용자가 상호 작용하는 앱의 위젯입니다.
양식에는 빌드 중인 앱 유형에 관계없이 사용할 수 있는 많은 컨트롤이 있습니다. 레이블, 버튼, 입력 상자, 이미지 및 물론 목록 보기와 같은 것입니다.
화면에 컨트롤을 추가할 때 레이아웃에 추가합니다. 화면에서 컨트롤이 정확히 어디에 나타나야 하는지 파악하는 것은 레이아웃입니다.
따라서 iOS 및 Android에서 각각 다음 화면을 생성하려면:
이 XAML을 사용했습니다.
<?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>
여기에서 몇 가지 중요한 일이 진행되고 있습니다.
첫 번째는 <StackLayout>
입니다. 이것은 스택에서 뒤따르는 모든 컨트롤을 정렬하도록 Forms에 지시합니다.
레이아웃에는 단 하나의 컨트롤만 있을 수 있으며 이는 <ListView>
이며 나중에 참조할 수 있도록 이름을 지정하겠습니다.
그런 다음 우리가 추구하는 것에 도달하기 전에 ListView
에 약간의 상용구 의식이 있습니다: <TextCell>
. 이것은 목록의 각 셀에 간단한 텍스트를 표시하도록 Forms에 지시합니다.
데이터 바인딩 이라는 기술을 통해 표시할 텍스트를 <TextCell>
에 알려줍니다. 구문은 Text="{Binding Name}"
과 같습니다. 여기서 Name
은 모델링하는 Recipe
클래스의 속성입니다... 음, Recipes입니다.
그러면 레시피가 목록에 어떻게 추가됩니까?
모든 XAML 파일과 함께 "코드 숨김" 파일이 있습니다. 이 코드 숨김을 통해 사용자 상호 작용 이벤트를 처리하거나 설정을 수행하거나 다른 앱 논리를 수행하는 등의 작업을 수행할 수 있습니다.
OnAppearing
이라고 하는 모든 Page
에서 재정의할 수 있는 함수가 있습니다. 이 함수는 짐작할 수 있듯이 Page
가 나타날 때 호출됩니다.
protected override void OnAppearing() { base.OnAppearing(); recipesList.ItemsSource = null; recipesList.ItemsSource = App.AllRecipes; }
recipesList.ItemsSource = AllRecipes;
이것은 ListView
에 "이봐! 모든 데이터는 열거 가능한 App.AllRecipes
(애플리케이션 전체 변수)에서 찾을 수 있으며 자식 개체의 속성을 사용하여 바인딩할 수 있습니다.”
조리법 목록은 모두 훌륭하고 훌륭하지만 먼저 조리법의 세부 사항을 보지 않고는 아무 것도 구울 수 없으며 다음에 처리하겠습니다.
이벤트 처리
사용자 터치에 응답하지 않고 우리 앱은 맛있는 소리가 나는 요리법 목록에 불과합니다. 소리는 좋은데 요리할 줄 모르면 소용없어요!
레시피를 만드는 방법을 볼 수 있도록 ListView
의 각 셀이 탭에 응답하도록 합시다!
RecipeListPage
코드 숨김 파일에서 컨트롤에 이벤트 핸들러 를 추가하여 사용자 상호 작용 이벤트를 수신하고 반응할 수 있습니다.
목록 보기에서 탭 이벤트 처리:
recipesList.ItemSelected += async (sender, eventArgs) => { if (eventArgs.SelectedItem != null) { var detailPage = new RecipeDetailPage(eventArgs.SelectedItem as Recipe); await Navigation.PushAsync(detailPage); recipesList.SelectedItem = null; } };
거기에 뭔가 깔끔한 일이 진행되고 있습니다.
누군가 행을 선택할 때마다 ListView
에서 ItemSelected
가 시작됩니다.
핸들러에 전달되는 인수 중 eventArgs
개체에는 이전에 ListView
에 바인딩된 항목인 SelectedItem
속성이 있습니다.
우리의 경우 Recipe
클래스입니다. (따라서 우리는 마스터 소스에서 객체를 검색할 필요가 없습니다 - 우리에게 전달됩니다.)
레시피 세부 정보 페이지
물론 비법과 조리법을 알려주는 페이지도 있는데 그 페이지는 어떻게 나오나요?
await Navigation.PushAsync(detailPage);
위에서 라인. Navigation
개체는 각 플랫폼에 대한 기본 방식으로 페이지 전환을 처리하는 플랫폼 독립적 개체입니다.
이제 레시피 세부정보 페이지를 살펴보겠습니다.
이 페이지도 XAML로 제작되었습니다. 그러나 사용된 Layout
(FlexLayout)은 CSS Flexbox에서 영감을 받았기 때문에 매우 멋집니다.
<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
은 컨트롤을 행이나 열로 정렬합니다. 큰 이점은 화면에 컨트롤을 배치할 공간이 얼마나 남았는지 자동으로 감지할 수 있고, 공간이 충분하지 않은 경우 이를 수용할 새 행이나 열을 자동으로 생성할 수 있다는 사실입니다!
이는 모바일 개발에서 많이 사용되는 다양한 화면 크기를 다룰 때 큰 도움이 됩니다.
글쎄, FlexLayout
이 세부 정보 화면을 보기 좋게 유지하는 데 도움이 되므로 여전히 해당 레시피를 편집해야 합니다. 그렇죠?
당신은 아마 이것을 알아차렸을 것입니다:
<ToolbarItem Text="Edit" Clicked="Edit_Clicked" />
그 라인은 앱의 툴바에 버튼을 넣는 역할을 합니다. Clicked="Edit_Clicked"
는 버튼이 클릭될 때 해당 이름의 기능에 대한 코드 숨김을 찾은 다음 해당 코드를 실행하도록 버튼에 지시합니다.
이 경우 레시피 편집 페이지를 인스턴스화하고 앞서 언급한 Navigation
개체를 사용하여 이를 탐색 스택에 푸시합니다.
레시피 편집 페이지
레시피 목록이 있는 페이지: 확인하세요! 조리법을 만들기 위한 모든 세부 정보가 있는 페이지: 확인하십시오! 이제 남은 일은 할머니가 마법을 부리는 것을 지켜보는 동안 레시피를 입력하거나 변경하는 데 사용할 페이지를 만드는 것뿐입니다!
먼저 화면을 확인하십시오.
이제 코드:
<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>
여기에 코드가 조금 더 있는데, 이는 Grid
레이아웃을 사용하여 모든 것이 2차원 패턴으로 배치되는 방식을 지정하기 때문입니다.
또한 여기에는 데이터 바인딩이 없습니다. 파일 이면의 코드에서만 컨트롤을 채우는 방법에 대한 예를 보여주고 싶었기 때문입니다.
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(); }; }
TheRecipe
속성이 보이시나요? 페이지 수준이며 특정 레시피에 대한 모든 데이터를 보유하고 페이지의 생성자에서 설정됩니다.
둘째, saveButton
및 cancelButton
에 대한 Clicked
이벤트 핸들러는 완전히 .NET화되었습니다(예, 저는 제 자신의 말을 꽤 자주 만듭니다.)
해당 이벤트를 처리하는 구문이 Java 또는 Objective-C에 고유하지 않기 때문에 .NET화되었다고 말합니다. 앱이 Android 또는 iOS에서 실행될 때 동작은 Android Click 또는 iOS TouchUpInside와 정확히 같습니다.
보시다시피 각 클릭 이벤트 핸들러는 레시피를 저장하고 페이지를 닫거나 페이지만 닫는 적절한 기능을 호출합니다.
여기 있습니다 — 지금부터 시간이 끝날 때까지 레시피를 저장할 수 있는 UI가 있습니다!
CSS 뭐?!? 또는 앱을 예쁘게 만들기
마지막을 위해 최선을 다하는 것: Xamarin.Forms 3.0은 무엇보다도 CSS를 사용하여 컨트롤의 스타일을 지정할 수 있는 기능을 제공합니다!
Xamarin.Forms CSS는 웹 개발에서 익숙한 100%가 아닙니다. 그러나 CSS에 익숙한 사람이라면 누구나 집처럼 편안하게 느낄 수 있을 만큼 가깝습니다. 할머니집에서 나처럼!
레시피 세부 정보 페이지를 가져와 리팩터링하여 XAML에서 모든 것을 직접 인라인으로 설정하는 대신 Cascading Style Sheets를 사용하여 시각적 요소를 설정하도록 하겠습니다.
첫 번째 단계는 CSS 문서를 만드는 것입니다! 이 경우 다음과 같이 표시됩니다.
.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; }
대부분 CSS처럼 보입니다. 거기에 수업이 있습니다. Image
클래스 유형에 대한 단일 선택기가 있습니다. 그런 다음 속성 설정자 무리입니다.
flex-wrap
또는 flex-basis
와 같은 일부 속성 설정자는 Xamarin.Forms에만 해당됩니다. 앞으로 팀은 표준 관행을 따르기 위해 접두사 xf-
를 붙일 것입니다.
다음은 XAML 컨트롤에 적용하는 것입니다.
<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>
이전의 모습입니다.
Xamarin.Forms에서 CSS 문서를 참조하려면 <StyleSheet Source="YOUR DOC PATH" />
를 추가합니다. 그런 다음 StyleClass
속성을 통해 각 컨트롤의 클래스를 참조할 수 있습니다.
확실히 XAML을 정리하고 컨트롤의 의도도 더 명확해집니다. 예를 들어, 이제 <BoxView StyleClass="spacer" />
가 무엇을 하는지 매우 명확해졌습니다!
그리고 Image
는 Image
이고 CSS에서 선택기를 정의한 방식이기 때문에 이미지 자체에 스타일이 지정됩니다.
확실히 Xamarin.Forms의 CSS는 웹 사촌만큼 완전히 구현되지는 않았지만 여전히 꽤 좋습니다. 선택자, 클래스가 있고 속성을 설정할 수 있으며 물론 전체 계단식 작업이 진행 중입니다!
요약
세 개의 화면, 두 개의 플랫폼, 하나의 기사, 끝없는 레시피 저장! 그리고 또 뭔지 알아? Android 및 iOS 이상의 Xamarin.Forms를 사용하여 앱을 빌드할 수 있습니다. UWP, macOS, 심지어 Samsung Tizen 플랫폼도 구축할 수 있습니다!
Xamarin.Forms는 사용자 인터페이스를 한 번 작성하고 주요 플랫폼에서 기본적으로 UI를 렌더링하여 앱을 만들 수 있는 UI 도구 키트입니다.
플랫폼에서 가장 일반적으로 사용되는 컨트롤에 대한 추상화인 SDK를 제공하여 이를 수행합니다. UI의 장점 외에도 Xamarin.Forms는 모든 기능을 갖춘 MVVM 프레임워크, 게시/구독 메시징 서비스, 애니메이션 API 및 종속성 서비스도 제공합니다.
Xamarin.Forms는 기존 Xamarin 개발과 동일한 코드 이점도 제공합니다. 모든 애플리케이션 로직은 모든 플랫폼에서 공유됩니다. 그리고 단일 언어를 사용하는 단일 IDE로 모든 앱을 개발할 수 있습니다. 정말 멋지네요!
다음은 어디로? 이 Xamarin.Forms 앱의 소스 코드를 다운로드하여 직접 사용해 보세요. 그런 다음 브라우저 내에서 앱을 만드는 기능을 포함하여 Xamarin.Forms에 대해 자세히 알아보려면 이 온라인 자습서를 확인하세요!