[Xamarin] Xamarin.Forms 4.0 Preview 소개

2019. 5. 23. 18:06Mobile/Xamarin

이 글은 2018년 12월 5일에 작성된 https://devblogs.microsoft.com/xamarin/xamarin-forms-4-0-preview/을 바탕으로 작성되었습니다. 본 문서에는 원문과 다른 내용추가, 삭제 및 변경을 다소 포함하고 있습니다.

Microsoft Connect(); 2018에서 Xamarin.Forms 4.0에 대한 개발계획과 공개 프리뷰가 발표되었습니다. 여기서는 Xamarin.Forms Shell부터 다른 주요한 변경사항에 대해 자세히 살펴볼 예정입니다.

우리는 무수한 인터뷰, 대화, 설문조사를 통해서 여러분들의 목소리를 아주 분명하게 들어왔습니다. 사람들은 Xamarin.Forms가 즉시 사용할 수 있을만큼 더 쉽고, 네비게이션은 항상 존재하면서 제어하기 쉽고, iOS와 Android 간의 디자인이 좀 더 일관되면서, 리스트 컨트롤은 더 빠르고 유연하게 동작하기를 희망하였습니다. Xamarin.Forms 4.0은 이러한 모든 최상위 의견에 대한 테마를 제공하며 Shell, Visual, CollectionView와 함께 더 많은 것을 제공합니다.

Shell 소개

우리는 어플리케이션을 설정 할 때 가이드를 좀 더 제시함으로써 Xamarin.Forms 시작을 더 쉽게 만들고 싶었습니다. Shell은 어플리케이션을 표현하기 위한 3단계 요소를 제공하며(아래에서 설명합니다) 이를 통해 여러분이 애플리케이션에 컨텐츠와 기능들을 손쉽게 채워넣을 수 있도록 합니다. Shell은 MasterDetailPage, NavigationPage, TabbedPage가 진화한 것으로 생각하실 수 있습니다.

Shell을 통해 얻을수 있는 것들

  • 단일 파일(AppShell.xaml)로 고수준의 애플리케이션 구조를 표현하는 단순화된 방법
  • 개발하려는 모바일 플렛폼에 적합한 공용 UI 네비게이션 계층구조: Flyout Menu, Bottom Tabs, Top Tabs
  • URI 기반 라우팅을 제공하는 견고한 네비게이션 서비스, 이를 통해 손쉽게 어플리케이션의 모든 부분으로 이동할 수 있음
  • UI 요소들을 손쉽게 수정할 수 있는 확장된 템플릿 기반 인프라
  • 현재 Xamarin.Forms에서 얻을 수 있는 모든 기능과 Shell 스펙 로드맵을 따라 제공될 다양한 기능들

이제 간단히 시작해봅시다. 만약 Windows Visual Studio 2019를 사용하고 있다면, Shell 기반 업데이트된 템플릿 패키지를 다운로드하고 인스톨하세요.(참고: 2019년 5월 Visual Studio 2019 정식버전과 Xamarin.Forms 4.0 Stable Release를 사용하고 계시면 이 과정을 불필요합니다.) 그 외에 어떤 IDE를 선호하든간에 상관없이, 이미 존재하는 어플리케이션이나 새로운 어플리케이션에 Shell을 손쉽게 추가하여 살펴보실 수 있습니다. 일단 어플리케이션을 열고 NuGet에서 Xamarin.Forms를 4.0-pre로 업데이트 하세요. (선호하는 Nuget 패키지 매니저를 통해 업데이트하실 수 있습니다.)

이제 Xamarin.Forms를 시작하기 전에 MainActivity.cs와 AppDelegate.cs에 Feature Flag를 추가하여 Shell을 활성화 해주세요. (참고: 2019년 5월 정식 출시된 Xamarin.Forms 4.0을 사용한다면 아래 Feature Flag 선언이 불필요합니다. Feature Flag는 정식 출시전 미리 기능들을 체험해보기 위해 사용하는 코드입니다.)

Android (MainActivity.cs):

global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental");
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

iOS (AppDelegate.cs):

global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental");
global::Xamarin.Forms.Forms.Init();

다음으로 XAML과 함께 ContentPage를 프로젝트에 추가하고 AppShell.xaml로 이름을 변경해주세요. (어떤 이름이든 상관없지만 당분간은 AppShell이라는 이름을 표준화으로 사용하고 있습니다.) 이제 AppShell.xaml.cs를 열고 Xamarin.Forms.Shell을 상속하도록 수정해주세요. 수정 후에는 다음과 같은 구조를 가질 것입니다.

<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:NewApp" 
    RouteScheme="app" 
    RouteHost="microsoft.com" 
    Route="newapp" 
    x:Class="NewApp.AppShell">
 
    <ShellItem Title="Home">
        <ShellSection>
            <ShellContent>
                <local:MainPage />
            </ShellContent>
        </ShellSection>
    </ShellItem>
 
</Shell>

위 XAML에서 local:MainPage에 주목해주세요. 이는 시작 페이지인 MainPage.xaml이 Local 네임스페이스에 위치해야 함을 의미합니다.

using System;
using System.Collections.Generic;
using Xamarin.Forms;
 
namespace NewApp
{
    public partial class AppShell : Xamarin.Forms.Shell
    {
        public AppShell()
        {
            InitializeComponent();
        }
    }
}

첫번째 Shell 애플리케이션을 실행하기 위해 남은 변경사항은 App을 열고 MainPage에 AppShell 인스턴스를 할당하는 것입니다. 아래와 같이 App.xaml.cs파일을 수정해주세요.

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
 
namespace NewApp
{
    public partial class App : Application
    {
        public App()
        {
           InitializeComponent();
 
            MainPage = new AppShell();
        }
    }
}

저장 후에 앱을 실행해보세요. 메인 페이지가 나타날 것이며 ☰ 메뉴 아이콘도 출력될 것입니다. 메뉴 아이콘을 클릭하면 하나의 네비게이션 메뉴를 포함하고 있는 Flyout이 열릴 것입니다. 이러한 변화를 만들어 낸 것은 위에서 언급한 3가지 요소 때문입니다:ShellItem, ShellSection, ShellContent. 사용자가 앱에서 더 깊이 네비게이션 할 수 있도록 Shell은 네비게이션 구조를 Flyout부터 하단 탭, 상단 탭을 설정합니다.

Element 설명
ShellItem Flyout 메뉴로 나타나는 최상위 레벨의 컨텐트 그룹입니다. 다수의 ShellSection을 포함할 수 있습니다.
ShellSection 앱의 컨텐트들을 그룹화합니다. 이 콘텐트들은 하단 탭을 통해 네비게이션할 수 있습니다. 1개 이상의 ShellContent를 포함할 수 있으며 ShellContent들은 상단의 탭으로 네비게이션됩니다.
ShellContent 앱의 ContentPage입니다.

네비게이션은 길들이기 까다로운 작업이 될 수도 있습니다: TabbedPage, MasterDetailPage, NavigationPage, Flyout을 설정하기 위한 일련의 플러그인과 커스텀 구현들, 네비게이션 이벤트 시 필요한 로직을 추가하는 것 처럼(뒤로가기 버튼을 취소하는 등) 까다로운 요구사항들이 있습니다. Shell에서는 언제 어디서든 원하는 곳으로 네비게이션할 수 있는 강력한 라우팅 API를 제공합니다.

네비게이션 라우팅

개발자들은 페이지를 띄우거나 제거하는 네비게이션 작업이 익숙하지만, 애플리케이션을 네비게이션하거나 사용자가 화면을 떠날 때 로직을 추가할 수 있는 더 나은 방법을 원한다고 요청하였습니다. Shell의 새로운 네비게이션은 이러한 문제를 해결하는 것을 목표로 하고 있으며 그 과정에서 추가적인 편의를 제공하고 있습니다. 이 작업은 위의 AppShell.xaml에서 라우팅을 정의하는 것으로 부터 시작합니다.

구분 설명
RouteScheme "http" 또는 "app"과 등의 URI Scheme을 지정합니다. 모바일 앱을 개발하는 것이므로 "app"이 더 적절합니다.
RouteHost URI의 Domain 부분입니다.
Route URI Base 부분입니다.

위 설정을 모두 조합하면 "app://microsoft.com/newapp"과 같은 앱의 루트 URI가 만들어집니다. 아래는 앱의 각 페이지에 대한 네비게이션을 설정하는 예제입니다. (상단 탭으로 나타나는 부분)

<ShellItem Title="Home" Route="a">
    <ShellSection Route="b">
        <ShellContent Route="home">
            <local:MainPage />
        </ShellContent>
        <ShellContent Route="notifications">
            <local:NotificationsPage />
        </ShellContent>
    </ShellSection>
</ShellItem>

위의 네비게이션 코드에 따르면 Notification 페이지로 이동하는 URI는 "app://microsoft.com/newapp/a/b/notifications"가 됩니다. 위 네비게이션 구조에 포함되지 않은 페이지로 라우팅하려면 먼저 코드 상에서 라우팅을 등록하는 것이 필요합니다.

Routing.RegisterRoute("greeting", typeof(GreetingPage));

위 예제코드는 사용자를 GreetingPage로 이동시키는 "greeting"이라는 새 라우팅을 등록합니다.

마지막으로 Shell 네비게이션 서비스를 통해 라우트를 실행하고 인사말을 전달하는 코드는 아래와 같습니다.

await (App.Current.MainPage as Shell).GoToAsync(new ShellNavigationState(new Uri("app://microsoft.com/newapp/greeting?msg=Hello")));

위 코드를 좀더 짧게 줄이면 아래와 같이 작성할 수 있습니다.

(App.Current.MainPage as Shell).GoToAsync("app:///newapp/greeting?msg=Hello");

QueryProperty

네비게이션이 발생할 때 Message를 전달하기 위해 쿼리스트링 매개변수를 사용할 수 있습니다. 쿼리스트링 문자열은 작은 정보를 전달하는데 적합합니다. 아래 예제와 같이 QueryProperty Attribute를 사용함으로써 전달받은 매개변수를 ContentPage 혹은 BindingContext의 Property로 전달받을 수 있습니다.

namespace NewApp.Pages
{
    //쿼리스트링 msg를 Message Property에 할당
    [QueryProperty("Message", "msg"]
    public partial class GreetingPage : ContentPage
    {
        public GreetingPage()
        {
            InitializeComponent();
        }
 
        string _message;
        public string Message
        {
            get { return _message; }
            set
            {
                _message = value;
            }
        }
    }
}

QueryProperty의 첫번째 매개변수는 값을 저장할 Property 이름이고 두번째 매개변수는 쿼리스트링 매개변수 명입니다. Shell 네비게이션은 페이지가 출력되기 전에 값을 할당합니다. 우리는 이 방법이 매우 유용하고 강력하다고 생각하지만, 사용하면서 생각한 의견이 있으시면 전달해주시기를 기대합니다.

샘플과 추가자료

Tailwind Traders 앱 스크린샷


Shell의 새롭고 강력한 네비게이션과 App Styling, Flyout과 메뉴의 수정, 그리고 하단 탭과 상단 탭의 설정 등 더 많은 정보를 원하시면 Tailwind Traders 모바일 앱(상단 사진)과 추가 자료들을 확인해주세요.

Visual: 플렛폼간 일관된 디자인 만들기

Xamarin.Forms를 사용하면 안드로이드와 iOS에서 동작하는 아름다운 네이티브 앱을 제작할 수 있습니다. 심지어 시간을 좀 더 투자한다면 Style, Effect, Custom Renderer를 통해 안드로이드와 iOS간 동일한 디자인을 얻을 수 있습니다. Visual은 일관된 컨트롤 테마를 제공함으로써 이러한 작업들을 보다 더 손쉽게 만드는데 목적이 있습니다. 현재 Visual은 구글에 의해 발표된 Material Design 스타일을 지원합니다. Xamarin.Forms 4.0-pre1은 Button, Entry, Frame, Progress에 대한 구현을 포함합니다. Visual이 구현된 화면을 보시면 안드로이드와 iOS간에 차이가 거의 없다는 것을 알게 될 것입니다. 이 모든 것은 ContentPage에서 Visual="Material"로 지정하는 것으로 끝이납니다. 이를 통해 Xamarin.Forms는 일관된 디자인과 경험을 구현하기 위해 스타일보다 더 깊은 대체 렌더러를 사용하게 됩니다.

Visual이 실제로 사용되기 전에 우리는 레이아웃과 디자인을 통합하기 위한 더 많은 컨트롤 작업들을 진행할 것입니다. 지금은 단지 미리보기 정도이며, 앞으로의 저희의 여정에 동참해주기를 바랍니다. 지금은 전적으로 Google Material Design에 집중하고 있지만 앞으로 Fluent, Fabric, Cupertino 등 다른 디자인 언어를 지원할 예정입니다.

Visual을 시작하기 위해 더 자세한 정보를 원하시면 프리뷰 문서를 확인해주세요.

CollectionView: 빠르고 유연한 리스트

사용자들은 유연한 레이아웃, 개선된 상호작용, 더 나은 성능을 제공하는 현대의 네이티브 리스트 컨트롤을 사용할 수 있게 해달라고 요청하였습니다. 그에 대한 응답으로 CollectionView가 만들어졌습니다. 추후 이 컨트롤에 대해 더 상세한 정보를 제공할 것입니다. 지금은 간략한 사용법에 대해 소개하도록 하겠습니다. Shell을 사용하기 위해 했던 것처럼 먼저 CollectionView를 사용하기 위해 "CollectionView_Experimental" Feature Flag를 선언해주세요. 안드로이드의 MainActivity.cs와 iOS의 AppDelegate.cs에 다음과 같은 Feature Flag 코드를 추가해주시면 됩니다. (참고: Xamarin.Forms 4.0 정식 출시 이후에는 Feature Flag를 선언할 필요가 없습니다. Xamarin.Forms 4.0 Preview 버전을 사용하시는 경우에는 아래 코드를 추가함으로써 CarouselView와 CollectionView를 활성화 할 수 있습니다.)

global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");

Feature Flag를 추가하셨으면 새로운 CollectionView를 다음과 같이 사용할 수 있습니다.

<StackLayout Margin="5">
    <Label HorizontalOptions="Fill" HorizontalTextAlignment="Center" 
            Text="Find the perfect space for your project." TextColor="{StaticResource ThemeColor}"></Label>
 
    <SearchBar x:Name="Search" HorizontalOptions="Center" BackgroundColor="White" TextColor="{StaticResource ThemeColor}" 
                PlaceholderColor="{StaticResource ThemeColor}" Placeholder="Search"></SearchBar>
 
    <CollectionView x:Name="Spaces" Margin="0,5,0,0">
        <CollectionView.ItemsLayout>
            <GridItemsLayout Span="2" Orientation="Vertical" />
        </CollectionView.ItemsLayout>
        <CollectionView.EmptyView>
            <StackLayout> 
                <Label FontAttributes="Bold" FontSize="18" Margin="10,25,10,10"
                        HorizontalOptions="Fill" HorizontalTextAlignment="Center" 
                        Text="No results matched your filter."></Label>
                <Label FontAttributes="Italic" FontSize="12" 
                        HorizontalOptions="Fill" HorizontalTextAlignment="Center"
                        Text="Maybe try a broader filter?"></Label>
            </StackLayout>
        </CollectionView.EmptyView>
    </CollectionView>
</StackLayout>

기본적으로 4가지 레이아웃 조합이 지원됩니다.

  • GridItemsLayout Horizontal
  • GridItemsLayout Vertical
  • ListItemsLayout Horizontal
  • ListItemsLayout Vertical

물론 직접 레이아웃을 구현할 수도 있습니다. 그러나 이는 좀더 상세한 설명이 필요하므로 다음에 다루도록 하겠습니다.

위 예제에서 EmptyView를 사용하고 있음을 주목해주세요. ItemSource가 비어있을 경우에는 EmptyView가 나타나게 됩니다. CollectionView와 CarouselView가 실제 동작하는 모습에 대해 간단히 살펴보시려면 GitHub의 TeamBuilder 데모 앱미리보기 데모앱을 확인해주세요.

더 많은 정보

곧 보게되실 Xamarin.Forms의 다음 Stable 릴리즈인 3.5.0은 다른 기능들도 포함되어 있습니다. 어떤 레이아웃에서도 BindingSource와 ItemTemplate를 사용할 수 있게 만드는 BindableLayout 예제를 살펴보세요. 아래 예제는 ScrollView와 StackLayout을 통해 가로 스크롤 리스트를 구현하고 있으며 BindableLayout을 사용하고 있습니다.

<ScrollView VerticalScrollBarVisibility="Never"
            HorizontalScrollBarVisibility="Always">
    <StackLayout BindableLayout.ItemsSource="{Binding ItemsSource}"
                 BindableLayout.ItemTemplateSelector="{StaticResource ItemTemplateSelector}"
                 Orientation="Horizontal"
                 Spacing="7"
                 Padding="10, 5" />
</ScrollView>

다음 버전 3.x버전에서 더 많은 개선사항이 있을 것입니다. 살펴보시려면 4.0 릴리즈 노트를 확인해보세요.

앞으로 진행될 작업

여기에 소개된 기능들은 앞으로의 Stable 릴리즈에서 달라질 수 있습니다. 우리의 목표는 2019년 봄에 있을 Visual Studio 2019의 Stable 릴리즈에 맞추어 Xamarin.Forms 4.0 버전을 동시에 발표하는 것입니다. 현재 핵심 기능들은 위에서 알려드린 바와 같이 Feature Flag 선언을 통해 사용하실 수 있습니다. 앞으로 있을 6주 간격의 릴리즈 주기에 맞춰 발표되는 3.x Stable 릴리즈에도 이 기능들이 포함되어 있을 것입니다. 4.0 Stable 릴리즈 발표 이전에 이러한 기능들이 여러분들의 앱에 일부분으로써 사용될 만큼 충분히 유용하다고 느끼실지는 모르겠습니다. Xamarin.Forms 4.0이 정식으로 공개될 때에는 Feature Flag가 사라지고 여러분들에게 제공되기를 희망합니다.

각 기능들의 진행상황을 확인하시려면 아래의 GitHub 링크에서 확인해주세요. 4.0 기능에 대한 사용자의견 설문조사에도 참여 부탁드립니다. 설문조사는 4.0 프리뷰 릴리즈 마다 새롭게 갱신될 것입니다.

 

'Mobile > Xamarin' 카테고리의 다른 글

[Xamarin.Forms] XAML Hot Reload  (0) 2019.08.06
[Xamarin.Forms] Fast Renderer  (0) 2019.06.04
[Xamarin.iOS] p12 인증서를 pfx로 변환  (1) 2017.12.06
[Xamarin] SkiaSharp 사용하기  (0) 2017.11.10
[Xamarin] Xamarin.Forms Previewer 오류  (0) 2017.09.21