2016년 4월 20일 수요일

Xamarin.Forms Guide, Webinar 대충 정리

죄송하게도 본 게시물은
아래 Xamarin 가이드를 보고 개인적으로 필요한 부분만을 정리한 것이므로
해당 링크를 직접 보시는 것이 좋습니다.
https://docs.xamarin.com/guides/xamarin-forms/


[Xamarin.Forms]

 : Cross-platform UI tookit으로 Android, iOS, Windows Phone에서 사용 할 수 있는 Native UI를 쉽게 만들 수 있게 해준다.
 : Xamarin.Forms을 사용하여 작성된 app은 결과적으로 Native application이므로 hybrid app과 같이 browser sand-boxing, limited APIs, performance 이슈가 없고 Platform에서 제공하는 feature들(CoreMotion/PassKit/StoreKit on iOS, NFC/Google Play Service on Android, Tiles on Windows)을 사용할 수 있음.
 : UI를 구현함에 있어 C#으로 모든 부분을 구현할 수 있고 XAML(Extensible Application Markup Language)을 사용하여 UI를 구성할 수도 있다.

[Xamarin.Forms Guide]

 : https://docs.xamarin.com/guides/xamarin-forms/

PDF Book Download
 : https://docs.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/

Xamarin에서 UI를 제공하는 방법에는 Xamarin.Forms을 사용하여 UI 관련 코드를 재사용하거나 Xamarin.iOS, Xamarin.Andoid를 사용하여 직접 Platform-specific API를 사용하는 두가지 방법이 있음.

Xamarin.Forms 사용이 적절한 App 종류는
 - Data entry apps
 - Prototypes and proofs-of-concept
 - Apps that require little platform-specific functionality
 - Apps where code sharing is more important than custom UI


Xamarin.iOS, Xamarin.Android 사용이 적절한 App 종류는
 - Apps that require specialized interactions
 - Apps with highly polished design
 - Apps that use many platform-specific APIs
 - Apps where custom UI is more important than code sharing


즉 GUI적으로 platform specific한 부분이 사용되거나
GUI적으로 좀 더 뭔가 advance한 처리가 필요한 경우에는 Xamarin.Forms가 부적절하겠음.


[Requirements]
: https://developer.xamarin.com/guides/xamarin-forms/getting-started/installation/

amarin.Forms applications can be written for the following operating systems:
  • Android 4.0.3 (API 15) or higher #
  • iOS 6.1 or higher
  • Windows Phone 8.1 (WinRT, using Visual Studio) #
  • Windows 8.1 Tablet/Desktop Apps (WinRT, using Visual Studio) #
  • Windows 10 Universal Apps (Phone/Tablet/Desktop, using Visual Studio)#
  • Windows Phone 8 Silverlight (using Visual Studio) DEPRECATED #

: iOS, OS X용을 개발하려면 Xcode 7이 필요하구나...

Any Xamarin Studio version from 5.0 can be used to develop Xamarin.Forms applications on OS X Yosemite (10.10) or newer. To develop iOS applications, Xcode 7 is also required.


[An Introduction to Xamarin.Forms]

: https://developer.xamarin.com/guides/xamarin-forms/getting-started/introduction-to-xamarin-forms/

UI를 구성하는데 있어 두가지의 방법이 있음.
 - C# 코드로 모두 구현하는 방법
 - XAML(Extensible Application Markup Language)을 사용하여 구성하는 방법

"Hello, Forms !"
public class App : Application
{
  public App ()
  {
    MainPage = new ContentPage {
      Content =  new Label
      {
        Text = "Hello, Forms !",
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
      }
    };
  }
}

[View and Layouts]

1. Pages
 : cross-platform mobile application screens
 : Xamarin.Forms Pages


2. Layouts
 : View를 담은 container의 역할
 :  Xamarin.Forms Layouts



3. Views
 : UI controls (ex labels, buttons, text entry boxes, etc.)
 : ActivityIndicator, BoxView, Button, DatePicker, Editor, Entry, Image, Label, ListView, OpenGLView, Picker, ProgressBar, SearchBar, Slider, Stepper, Switch, TableView, TimePicker, WebView
 :  Xamarin.Forms Views

4. Cells
 : list의 item 표시에 특화되어 각 item을 표시할 때 사용 됨.
 : EntryCell, SwitchCell, Text Cell, ImageCell
 : Xamarin.Forms Cells


[Model-View-ViewModel (MVVM)]

 : http://hackersstudy.tistory.com/71
 : http://secretroute.tistory.com/entry/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4MVC-MVP-and-MVVM
 : 기존 MVC의 문제와 MVP의 문제를 해결하고자 나온 Architectural model 이며 View Model와 View간의 dependency를 줄이고자 나온 것이며 Command와 Data binding을 사용하여 해결한다고 함.

[Data Binding]

Data binding은 source와 target를 연결한다. source는 data를 제공하고 target은 source에서 제공한 data를 사용한다.


binding의 이점은 data와 view간의 동기화를 걱정할 필요가 없다는 점이고 data 변경 시 source object는 자동으로 binding framework에 등록된 target object로 변경사항을 보내게 된다.

View의 control(target)과 ViewModel의 model(source)을 binding을 위해 다음 두 절차가 필요하다. (하단 샘플 참고)
- View의 BindingContext property로 source(ViewModel의 model)이 지정 되어야 한다.
- View의 control과 ViewModel의 model간의 binding은 XAML의 Binding markup extension이나 C#의 SetBinding() 방법을 사용해야 한다.

[Xamarin.Forms Webinar]

 : Xamarin.Forms 관련 개념 설명, 기본 Layout, View 예제 code, MVVM 관련 예제 code와 설명이 괜찮다.
 : https://fast.wistia.net/embed/iframe/w2p6ayviev?popover=true
 : http://www.slideshare.net/Xamarin/introduction-to-xamarinforms


[Page, Layout, Controls Demo 예제인 ListPage 코드]
 : Demo에서는 TabbedPage(TimeListPage)를 사용하여 두개의 ContentPage를 사용하는 예제임.
 : ContentPage 중 하나인 ListPage에서는 StackLayout를 사용하여 Button Control과 버튼 클릭 시간을 보여주는 ListView를 보여주며 Page, Layout, Control들의 간단한 사용, 추가 방법에 대해서 알려줌.

using Xamarin.Forms;

namespace App1
{
    public class ListPage : ContentPage
    {
        ObservableCollection<string> Items;
        public ListPage()
        {
            Title = "List Page";
            Items = new ObservableCollection<string>();
            var list = new ListView();

            list.ItemsSource = Items;
            list.ItemSelected += (sender, args) =>
            {
                if (list.SelectedItem == null)
                    return;

                this.Navigation.PushAsync(new ContentPage
                {
                    Title = "page 2",
                    Content = new Label
                    {
                        Text = args.SelectedItem as string
                    }
                });
                list.SelectedItem = null;
            };

            var button = new Button
            {
                Text = "Add Time"
            };

            button.Clicked += (sender, args) =>
            {
                Items.Add(DateTime.Now.ToString("F"));
            };

            var stack = new StackLayout
            {
                Orientation = StackOrientation.Vertical,
                Spacing = 10,
                Children = { list, button }
            };

            Content = stack;
        }
    }

    public class TimeListPage : TabbedPage
    {
        public TimeListPage()
        {
            this.Title = "Time List";
            Children.Add(new ListPage());
            Children.Add(new ContentPage
            {
                Title = "Tab2",
                Padding = 10,
                Content = new Label
                {
                    Text = "Hello from Tab 2"
                }
            });
        }
    }
}

[MVVM, Binding 예제인 LoginPage 관련]





: username, display 변경 관련
 . View(LoginPage)의 entry가 UsernameViewModel의 Username과 Binding 되었음.
 . ViewModel(UsernameViewModel)에서 INotifyPropertyChanged의 PropertyChanged()를 호출하여 username과 Display가 변경되었음을 알릴 수 있음.
 . View(LoginPage)의 label이 UsernameViewModel의 Display와 Binding 되어 있기 때문에 label의 text property가 업데이트 되게 됨.


Command, Action
 : Command에는 실행할 Action과 실행 가능여부를 확인하는 Action이 정의 됨.

namespace Xamarin.Forms
{
    //     Defines an System.Windows.Input.ICommand implementation wrapping a generic Action<T>.
    //
    //     The following example creates a new Command and set it to a button.
    public sealed class Command<T> : Command
    {
        public Command(Action<T> execute);
        public Command(Action<T> execute, Func<T, bool> canExecute);
    }
}

namespace System
{
    public delegate void Action<in T>(T obj);
}

 : button 클릭 시
  . loginCommand은 실행할 ExeuteLoginCommand Action과 실행 여부를 확인하는 CanLogin Action을 가지는 Command로 초기화 됨.
  . View(LoginPage)의 button은 UsernameViewModel의 LoginCommand와 binding되어 있어 button 클릭 시 LoginCommand에 Username 값을 parameter로 넘겨 실행한다.
 . ViewModel(UsernameViewModel)의 CanLogin에서 username을 확인한 뒤 ExecuteLoginCommand가 호출되어 TimeListPage로 이동하게 된다.


using Xamarin.Forms;

namespace App1
{
    public class UsernameViewModel : INotifyPropertyChanged
    {
        private INavigation navigation;
        public UsernameViewModel(INavigation navigation)
        {
            this.navigation = navigation;
        }
        private string username = string.Empty;
        public string Username
        {
            get { return username; }
            set
            {
                if (username == value)
                    return;

                username = value;
                OnPropertyChanged("Username");
                OnPropertyChanged("Display");
            }
        }

        private Command<string> loginCommand;
        public Command LoginCommand
        {
            get { return loginCommand ?? (loginCommand = new Command<string>(ExecuteLoginCommand, CanLogin)); }
        }

        private bool CanLogin(string name)
        {
            return !string.IsNullOrWhiteSpace(name);
        }

        private void ExecuteLoginCommand(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                return;
            navigation.PushAsync(new TimeListPage());
        }

        public string Display
        {
            get { return "Hello there: " + username; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string name)
        {
            if (PropertyChanged == null)
                return;

            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

    public class LoginPage : ContentPage
    {

        public LoginPage()
        {
            this.BindingContext = new UsernameViewModel(Navigation);

            var entry = new Entry
            {
                Placeholder = "Enter Username"
            };

            entry.SetBinding<UsernameViewModel>(Entry.TextProperty,
                vm => vm.Username, BindingMode.TwoWay);

            var label = new Label
            {

            };

            label.SetBinding<UsernameViewModel>(Label.TextProperty,
                vm => vm.Display);

            var button = new Button
            {
                Text = "Login"
            };

            button.SetBinding<UsernameViewModel>(Button.CommandProperty,
               vm => vm.LoginCommand);
            button.SetBinding<UsernameViewModel>(Button.CommandParameterProperty,
               vm => vm.Username);

            Content = new StackLayout
            {
                Padding = 10,
                Spacing = 10,
                Children = { entry, label, button }
            };

        }
    }
}

XAML도 봐야 하는데...

댓글 없음:

댓글 쓰기