Xamarin 공부를 하고 있는 중에 axml 파일이 디자이너로 보여지지 않고 아래와 같은 에러가 발생

Your Java Version(1.0.7) is too old, You must have at least 1.8 installed.
자바 버전이 문제라는 메세지이기 때문에
자바 버전을 최신으로 깔아도 여전히 문제 발생

구글링을 열심히 하고 있는 와중에 옵션쪽에 설정하는 부분이 있다는 말에 바로 찾아보니
아래와 같이 자바버전이 잘못 설정이 되어있었음  ㅜㅠ


최신 버전이 있는 곳으로 위치 변경.
C:\Program Files\Java\jdk1.8.0_121
다시 axml 디자이너를 여니 아래와 같이 제대로 디자이너가 동작함.

이 외 문제들은 SDK Manager 에서 필요한 항목을 설치 및 업데이트하면 된다.

 

참고

http://stackoverflow.com/questions/30090719/view-designer-not-showing-up

Error: String types not allowed (at 'textColor' with value 'Black').

갑자기 에러가 발생되었다..

색깔은 허용되지 않는다는건가.. #000000 해보고 black 를 넣어도 해결이 안되어

다시 보니 아예 textColor 을 쓸수 없는가보다;

textColor 항목을 뺴니 해결이 되었다.

CheckBox, LinearLayout 에는 textColor 를 쓸수 없다.

 

Xamarin Forms 를 이용한 많은 앱들이 생겨나고 있습니다.

대표 네이버 카페를 가보면

https://play.google.com/store/apps/details?id=kr.njhouse.alltheair

https://play.google.com/store/apps/details?id=com.spoonful_lab.SpoonfulMessenger

등등

위그림에서 보듯이 많은 앱들이 만들어 지고 있습니다.

여기 가입한 분들이 다가 아닐테니.. 더 많을 것입니다.

또한 스타트업 회사들에서도 점점 Xamarin Forms 개발자를 구하는 공고가 조금씩 보이기 시작하고 있습니다.

하지만 아직 표면적으로는 느껴지지는 않는 상황이라는....

그래서 저도 처음 시작할떄 많이 망설이기도 했던게 사실입니다;

어쨌든.... (쓸데없는말이 길었군요)

 

오늘은 Xamarin Forms 으로 계산기를 만들어 보려고 합니다.

대략 순서는 아래와 같습니다.

1. 프로젝트 생성 (cross-flatform)

2. 화면에서 사용될 model 구성

3. 계산기 화면 구성

 

프로젝트를 생성합니다 cross-flatform 을 선택하여 솔루션을 구성합니다.

아래처럼 프로젝트가 생성 됩니다.

전 타이젠도 추가했습니다.

타이젠 추가방법은 이전 포스팅에 있습니다. http://kjcoder.tistory.com/225

 

우선 화면에서 사용될 model 을 생성합니다.

이 model 에 화면에서 처리될(숫자표현, 연산처리등) 내용이 모두 들어가 있습니다.

그 다음 클래스를 추가합니다. StudyViewModel 이라고 명명하겠습니다.

(설명은 코딩내에 다있습니다.)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;

namespace XamarinFormsStudy
{
    public class StudyViewModel : INotifyPropertyChanged
    {
        /// <summary>
        /// 연산자 입니다.
        /// </summary>
        public string Op { get; set; }
        /// <summary>
        /// 계산할 데이터 입니다. 이전입력값
        /// </summary>
        public double Op1 { get; set; }
        /// <summary>
        /// 계산할 데이터 입니다. 현재입력값
        /// </summary>
        public double Op2 { get; set; }
        /// <summary>
        /// 출력창에 입력문자를 보여주도록하는 명령입니다.
        /// </summary>
        public ICommand AddCharCommand { protected set; get; }
        /// <summary>
        /// 출력창의 문자를 하나씩 삭제하는 명령입니다.
        /// </summary>
        public ICommand DeleteCharCommand { protected set; get; }
        /// <summary>
        /// 출력창의 모든 문자를 삭제하는 명령입니다.
        /// </summary>
        public ICommand ClearCommand { protected set; get; }
        /// <summary>
        /// 연산자 입력시 처리하는 명령입니다.
        /// </summary>
        public ICommand OperationCommand { protected set; get; }
        /// <summary>
        /// 연산결과를 도출하는 명령입니다.
        /// </summary>
        public ICommand CalcCommand { protected set; get; }

        // 출력될 문자들 담아둘 변수
        string inputString = "";
        public string InputString
        {
            protected set
            {
                if (this.inputString != value)
                {
                    this.inputString = value;
                    OnPropertyChanged("InputString");
                    this.DisplayText = this.inputString;

                    //삭제 버튼을 활성화/비활성화 합니다.
                    ((Command)this.DeleteCharCommand).ChangeCanExecute();
                }
            }
            get { return this.inputString; }
        }
          
        // 출력 텍스트 박스에 대응되는 필드
        string displayText = "";
        public string DisplayText
        {
            protected set
            {
                if (this.displayText != value)
                {
                    this.displayText = value;
                    OnPropertyChanged("DisplayText");
                }
            }

            get { return this.displayText; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public StudyViewModel()
        {
            // 출력창에 입력 문자를 출력합니다.
            this.AddCharCommand = new Command<string>((Key) => { this.InputString += Key; });
            // 입력문자열이 0보다 큰 경우 마지막에서 하나씩 삭제합니다.
            this.DeleteCharCommand = new Command(
            (nothing) =>
            {
                this.InputString = this.InputString.Substring(0, this.InputString.Length - 1);
            },
            (nothing) =>
            {
                return this.InputString.Length > 0;
            }
            );

            // 초기화
            this.ClearCommand = new Command((nothing) =>
            {
                this.InputString = "";
            });

            // 연산자가 들어오면 연산자와 입력문자를 전역에 담습니다.
            this.OperationCommand = new Command<string>((key) =>
            {
                this.Op = key;
                this.Op1 = Convert.ToDouble(this.InputString);
                this.InputString = "";
            });

            // 전역에 담겨진 연산자와 입력문자열 기준으로 계산하여 출력창에 나타냅니다.
            this.CalcCommand = new Command<string>((nothing) =>
            {
                this.Op2 = Convert.ToDouble(this.InputString);

                switch (this.Op)
                {
                    case "+":  this.InputString = (this.Op1 + this.Op2).ToString(); break;
                    case "-": this.InputString = (this.Op1 - this.Op2).ToString(); break;
                    case "*": this.InputString = (this.Op1 * this.Op2).ToString(); break;
                    case "/": this.InputString = (this.Op1 / this.Op2).ToString(); break;

                }
           
            });
        }

        /// <summary>
        /// 항목변경에 따른 이벤트입니다.
        /// </summary>
        /// <param name="propertyName"></param>
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}

 

ContentPage 를 추가합니다.

아래 처럼 코딩합니다. (설명은 코딩내에 다있습니다.)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamarinFormsStudy;assembly=XamarinFormsStudy"
             x:Class="XamarinFormsStudy.CalcPage">

    <Grid HorizontalOptions="Center" VerticalOptions="Center">
        <!--그리드에 바인딩될 모델을 설정합니다.-->
        <Grid.BindingContext>
            <local:StudyViewModel/>
        </Grid.BindingContext>
        <!--계산기의 기본 레이아웃을 잡습니다. row 6, col 4-->
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
       
        <!--상단에 계산기 인걸 표시해줍니다. "Calc"-->
         <Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <Frame Grid.Column="0">
                <Label Text="Calc"
                       HorizontalTextAlignment="Center" VerticalTextAlignment="Center"
                       IsVisible="True" FontAttributes="Bold" TextColor="Black"/>
            </Frame>
        </Grid>

        <!--가장 윗줄인 숫자가 보여질 영역과 삭제, 초기화 버튼을 위치시킵니다.-->
        <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <Frame Grid.Column="0" OutlineColor="Accent">
                <Label Text="{Binding DisplayText}"/>
            </Frame>
           
            <!--여기서 각버튼마다 model 에 정의된 명령을 연결시켜주었습니다.-->
            <Button Text="<"   Command="{Binding DeleteCharCommand}"   Grid.Column="1" BorderWidth="0"/>
            <Button Text="C"    Command="{Binding ClearCommand}"        Grid.Column="2" BorderWidth="0"/>
        </Grid>
        <!--
        숫자와 연산기호를 정의합니다.
        숫자와 연산기호 또한 model 에 정의된 명령을 연결시켜줍니다.
        -->
        <Button Text="1" Command="{Binding AddCharCommand}" CommandParameter="1" Grid.Row="2" Grid.Column="0"/>
        <Button Text="2" Command="{Binding AddCharCommand}" CommandParameter="2" Grid.Row="2" Grid.Column="1"/>
        <Button Text="3" Command="{Binding AddCharCommand}" CommandParameter="3" Grid.Row="2" Grid.Column="2"/>
        <Button Text="+" Command="{Binding OperationCommand}" CommandParameter="+" Grid.Row="2" Grid.Column="3"/>
       
        <Button Text="4" Command="{Binding AddCharCommand}" CommandParameter="4" Grid.Row="3" Grid.Column="0"/>
        <Button Text="5" Command="{Binding AddCharCommand}" CommandParameter="5" Grid.Row="3" Grid.Column="1"/>
        <Button Text="6" Command="{Binding AddCharCommand}" CommandParameter="6" Grid.Row="3" Grid.Column="2"/>
        <Button Text="-" Command="{Binding OperationCommand}" CommandParameter="-" Grid.Row="3" Grid.Column="3"/>
       
        <Button Text="7" Command="{Binding AddCharCommand}" CommandParameter="7" Grid.Row="4" Grid.Column="0"/>
        <Button Text="8" Command="{Binding AddCharCommand}" CommandParameter="8" Grid.Row="4" Grid.Column="1"/>
        <Button Text="9" Command="{Binding AddCharCommand}" CommandParameter="9" Grid.Row="4" Grid.Column="2"/>
        <Button Text="*" Command="{Binding OperationCommand}" CommandParameter="*" Grid.Row="4" Grid.Column="3"/>
       
        <Button Text="0" Command="{Binding AddCharCommand}" CommandParameter="0" Grid.Row="5" Grid.Column="0"/>
        <Button Text="." Command="{Binding AddCharCommand}" CommandParameter="." Grid.Row="5" Grid.Column="1"/>
        <Button Text="=" Command="{Binding CalcCommand}" CommandParameter="=" Grid.Row="5" Grid.Column="2"/>
        <Button Text="/" Command="{Binding OperationCommand}" CommandParameter="/" Grid.Row="5" Grid.Column="3"/>

    </Grid>
</ContentPage>

계산기가 만들어졌습니다.

이제 결과를 확인해 볼까요...

각 장치마다 UI 가 조금씩 다릅니다.

그럼 각 장치에 맞는 추가 코딩을 넣어주어야합니다.

이런게 Xamarin Forms 의 한계점이라고 볼수 있습니다;;;

 

Tzien

 

 

Android

 

iOS

 

Universal

 

소스를 첨부하고 싶지만 너무 용량이 커서 Git 주소로 대채합니다.

https://github.com/knagjun/XamarinFormsStudy

Xamarin Forms 에서 타이젠도 개발이 가능하다는 말에

환경설정을 한번 해보기로 했습니다.

일단 결론은 잘 실행된다 입니다.

Tizen 으로 멀 만들어 봐야 효용성은 없겠지만..

Xamarin Forms 로 구성이 가능하다니.. 정말 안되는게 없다라는게 느껴지네요

 

1. Hyper-V 기능끄기

Hyper-V 를 사용하고 계신분이 라면 일단 기능을 꺼야합니다.

프로그램 및 기능에서 Windows 기능 켜기/끄기 로 들어가서

Hyper-V 가 체크 해제되어있어야합니다.

 

2. Intel® Hardware Accelerated Execution Manager (Intel® HAXM) 다운 및 설치

https://software.intel.com/en-us/android/articles/intel-hardware-accelerated-execution-manager

위 링크로 들어가 haxm-windows_v6_1_2.zip (6.1.2) 를 다운받습니다.

용랑이 작아서 이건 첨부 합니다. :

haxm-windows_v6_1_2.zip

제일 아래에 링크를 누르면 다운됩니다.

 Click to Accept EULA & Download haxm-windows_v6_1_2.zip (6.1.2)

압축을 풀고 intelhaxm-android.exe 를 실행합니다.

특별히 선택할 건 없습니다. 그냥 쭉~~ 설치하면 됩니다.

설치가 완료되었습니다.

 

3. Visual Studio Tools for Tizen Preview 다운 및 설치

Visual Studio 에서 동작하게 하기위해 설치해야합니다.

https://developer.tizen.org/development/tizen-.net-preview/getting-started?langredirect=1

위 링크로 들어가 Origin 을 클릭해서 다운 받습니다. (Origin 이 아닌 다른곳에서 다운받아도 무방합니다.)

 

945MB 크기가 다운받아져야해서 좀 시간이 걸릴수도 있습니다.

다운이 완료되면 설치합니다.

이것도 특별히 설정한건 없습니다. 다 Next 합니다.

이제 설치하면서 자기가 알아서 Visual Studio 에 맞는걸 찾아서 설치합니다.

전 참고로 Visual Studio 2015, 2017 두개가 설치되어있는데

두버전으로 각각 설치가 진행되었습니다. (아래 그림참고)

설치가 모두 완료되었습니다.

Visual Studio 를 엽니다

도구를 클릭하여 Tizen 이 보이면 일단 설치는 정상 적으로 된것입니다.

 

4. 애뮬레이터 실행

Tizen 애뮬을 한번 실행해 봅니다.

도구>Tizen>Tizen Emulator Manager 를 선택합니다.

에뮬레이터 관리자가 실행되고 Create 를 선택합니다.

mobile 에서 아래처럼 선택합니다.

(Tizen 이 TV 도 있나보군요;)

폰 종류를 선택합니다.

Finish 를 합니다.

그럼 에뮬레이터가 하나 생성이 완료되었고 이를 Launch 합니다.

액세스 허용하고

Tizen 에뮬 전원이 켜지고 있습니다.

에뮬레이터가 잘 작동하는구요 오호....

 

5. 프로젝트 추가

Xamarin Forms 를 해보신 분이라면 아시겠지만 Corss-platform 을 선택하고 프로젝트를 실행하면 Tizen 은 자동 생성되지 않습니다.

아래 그림보시면 ios, android, uwp 프로젝이 생성되어있습니다.


Tizen 은 수동으로 추가해야합니다.

새프로젝트를 추가합니다.

오호 새프로젝트 목록에 Tizen 이 생겼네요

Blank App 를 선택하고 확인합니다.

프로젝트 추가가 완료되었습니다.

Tizen 프로젝트를 시작프로젝트로 하고 실행해 보겠습니다.

오 잘 구동이 되는군요 따로 코딩을 하지 않아도 알아서 공유 프로젝트를 바라보도록 코딩이 되어있습니다.

 

Xamarin Forms 를 하면서 가장 보고 싶었던게 iOS 구동화면 이었습니다.

안드로이드 , Windows 는 바로 결과를 확인할 수 있지만 iOS 는 그렇지 않기 때문이죠

지난 포스팅에서 VMWare 에 Mac 환경 구성을 완료했습니다.

VMWare 에 Mac 환경 구축하기 - 1 :http://kjcoder.tistory.com/209

VMWare 에 Mac 환경 구축하기 - 2 : http://kjcoder.tistory.com/212

이제 Mac 에서 디버깅이 가능하도록 개발 환경을 구성해볼까요?

 

우선 원격 로그인이 가능하도록 설정해야합니다.

사과로고 > 시스템환경설정 > 공유로 접근합니다. (이미지는 영문)

아래 그림과 같이 원격 로그인과 원격 관리를 체크해 주고 전체 사용자가 접근 가능하도록 해줍니다.

(전체사용자를 원하지 않으면 특정 사용자를 지정해도 됩니다.)

이제 iOS 개발 도구인 Xcode 를 설치합니다.

App Store 에서 Xcode 로 검색하면 가장 처음에 있습니다. (참고로 제 Mac 환경을 시에라 버전입니다.)

Agree(동의) 합니다.

설치가 진행됩니다. 설치에 좀 시간이 소요됩니다. 좀 많이...

설치가 완료되면 아래처럼 나타납니다.

이제 Visual Studio 를 설치합니다.

http://xamarin.com/download 링크로 이동하고 아래 화면의 내용을 적당히 채운 후 다운로드 받습니다.

Full Name (이름)은 중간에 공백이 있어야 제대로 인식됩니다. (에고 이미지는 공백이 없군요 저렇게 하면 안됩니다. "kang jun" 이런식으로...)

다운로드가 완료되면 하단에 다운로드 아이콘이 활성화되고 누르면 현재 다운로드 받은 Visual Studio 가 보이게 됩니다.

더블 클릭하게되면 아래처럼 install Visual Studio 설치 창이 나타압니다. 화살표를 더블클릭합니다.

Open 합니다.

설치 준비 중입니다.

설치해 줘서 고마워 계속(Continue..)

Android 는 솔직히 필요없는데 Mac 에서 Android 애뮬이 어떻게 뜰지도 궁금해서 체크했습니다.

가장 아래 Workbooks & inspector 는 사용 안할 것이므로 체크 해제합니다.

(사용하실분들은 설치하셔도 무방합니다.)

이제 다운로더가 실제 Visual Studio 설치 파일등 구동에 필요한 파일들을 다운받기 시작하네요

내 Mac 에 변화가 일어날 것을 허락하겠냐.. 그렇다.. 비번을 넣고 OK 합니다.

이 작업도 좀 시간이 걸립니다. 요건 xcode 보다는 좀 짧지만 깁니다.

시간이 걸려서 봤더니 설치가 실패했군요..

그래도 다시 첨부터 할수 없으니 일단 Retray 해봅니다.

다행히 설치가 완료되었습니다.

설치 이후에 재부팅하거나 하면 업데이트가 또 뜹니다. 그때 모두 업데이트 해주는게 좋습니다.

이제 Mac 의 IP 주소를 알아야 합니다.

시스템 환경설정의 네트워크를 열면 IP 주소를 알수 있습니다.

192.168.142.128 이네요

 

Visual Studio 를 열고

도구 > 옵션 에서 Xamarin > iOS 설정 을 들어갑니다.

(아래 화면은 이미 설정하고 난 뒤 이미지이며 원래는 IP 주소가 없습니다.)

Xamarin Mac Agent 찾기 를 클릭합니다.

자동으로 잡히는 것도 있긴한데 이건 다 가짜? 입니다. VMWare 가 가짜? 라서 그런지 모르겠지만;; (아무리 해도 저건 연결이안됩니다.)

하단의 Mac 추가 를 클릭합니다.

아까 Mac 의 네트워크 정보에 있던 IP 를 넣습니다. 192.168.142.128

그럼 아래처럼 원격 Mac 를 찾습니다. 아래는 열심히 찾는 중이네요.

아래처럼 클립 모양이 되면 연결준비가 완료된 것입니다.

연결 버튼을 클릭합니다.

연결이 완료 되면 아래처럼 IP 가 나타나게됩니다.

이제 디버깅을 해보겠습니다.

디버깅시 반드시 아래처럼 설정을 바꾸고놓고 진행해야합니다.

(기본값이 다른걸로 되어있습니다.)

아래처럼 시뮬레이터가 동작하려는 준비 과정을 거치면

아래처럼 Mac PC 에서 iPhone 시뮬레이터가 뜨면서 동작하는걸 볼수 있습니다.

또한 아래처럼 windows 에서 애뮬로도 구동이 가능합니다.

참고로 출력창을 아래 Xamafin Diagnostics 로 바꾸면 진행 상황을 확인 할수 있습니다.

 

이제 iOS 까지 구동을 해보았네요

다음 시간에는 타이젠으로 구동하는 방법을 알아 볼까합니다.

 

참고로 시뮬레이터가 제대로 동작하지 않는 경우 아래 파일을 설치해 보고

재시도 해 보시기 바랍니다.

Xamarin.Simulator.Installer.1.0.2.7.msi

Xamarin 은 Xamarin.IOS,Xamarin.Android, Xamarin.UWP 등 각 장치에 따라 개발이 가능하도록 되어있습니다.

하지만 이렇게 개발하게 되면 각 장치에 따른 언어로 개발이 이루어 져야합니다.

Android  는 Java 로 IOS 는 xcode 로 말이죠

당연히 C# 스럽게 Xamarin 에서 만들어 주긴했지만 이건 더 개발자를 헷갈리게 하는 부분도 있습니다.

그래서 이를 해결하고자 하는게 Xamarin.Forms 입니다.

완전히 각 장치의 내용을 몰라도 되는것은 아닙니다.

각 UI 계층에 대한 API 를 사용하긴하되 얇야지게 된다고 보면됩니다.

이를 위해 Xamarin.Forms 에서 제공되는 새로운 방식을 습득해야합니다.

말이 길었네요 그럼 시작해 보겠습니다.

 

새로운 솔루션을 만듭니다. (Visual Studio 2015)

Cross-Platform 의 플랫폼 간 앱(Xamarin.Forms 또는 네이티브) 를 선택합니다.

UI 기술은 Xamarin.Forms 를 코드 공유 전략은 이식 가능한 클래스 라이르버리를 선택하여 프로젝트를 선택합니다.

공유 코드의 2가지 작성법

공유 코드를 작성하는 방법은 크게 '공유 프로젝트'와 '이식 가능한 클래스 라이브러리'로 나누어집니다.

공유 프로젝트 (Shared Project)

공유 프로젝트란 공유 프로젝트를 만들어 거기에 공통으로 사용할 코드를 C#으로 작성하고 각각의 Android, iOS, Windows 프로젝트에서 참조해 사용하는 방식입니다.

공유 프로젝트는 단지 공통 코드를 모아 놓은 집합체일 뿐이고 output이 생기지 않습니다. 각 프로젝트들이 해당 소스 코드를 자기의 프로젝트 안에 있는 것처럼 가져다가 컴파일 할 뿐입니다.. 즉, 일종의 폴더 역할 밖에 하지 않는 것입니다. 당연히 별도의 .DLL이나 .class가 생기는 클래스 라이브러리와는 차이가 있습니다. output이 없으므로 소스 없이는 다른 App 개발에 공급해서 사용할 수 없습니다.

반면, 소스 코드가 그대로 사용되므로 #if __ANDROID__처럼 컴파일 지시자를 이용해 특정 플랫폼에서만 동작하는 코드 블록을 만들 수 있습니다.

 이식 가능한 클래스 라이브러리 (Portable Class Library)

PCL이라고도 불리는 '이식 가능한 클래스 라이브러리'는 소스 코드가 직접 사용되는 공유 프로젝트와는 달리 output이 생기며 소스 코드 없이도 해당 output만을 다른 업체에 재공할 수 있습니다. PCL로 작성하면 Xamarin.iOS, Xamarin.Android뿐만 아니라 WPF, Windows App, 심지어는 XBox 등에서 사용할 수 있습니다.

하지만 플랫폼 의존적인 코드를 작성할 수 없고 플랫폼 의존적인 다른 라이브러리도 포함시킬 수 없습니다. Android와 iOS, Windows App에 공통적인 내용들로만 라이브러리가 구성됩니다.

UWP 는 버전을 선택하라고 뜹니다. 버전을 지정합니다. 일단 Default 로 진행합니다.

IOS 는 Mac 을 찾습니다. Mac 은 오고 있는 중이므로 일단 Pass 합니다. ( X 닫기)

아래처럼 솔루션이 구성됩니다.

각 프로젝트를 보시면 아시겠지만 모두 이식 가능 프로젝트의 App 를 호출하고 있습니다.

Android

 [Activity(Label = "XamarinStudy", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }

IOS

    // The UIApplicationDelegate for the application. This class is responsible for launching the
    // User Interface of the application, as well as listening (and optionally responding) to
    // application events from iOS.
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        //
        // This method is invoked when the application has loaded and is ready to run. In this
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }
    }

UWP

    public sealed partial class MainPage
    {
        public MainPage()
        {
            this.InitializeComponent();

            LoadApplication(new XamarinStudy.App());
        }
    }

이제 이식 가능한 프로젝트에 각 장치에서 보여질 화면을 하나 만들어 보겠습니다.

Content Page 는 C#  과 xaml 파일로 만들 수 있습니다. 전 C# 으로 만들었습니다.

내부에 아래 처럼 코딩합니다.

화면에 Welcome to Xamarin Forms! 를 출력하는 단순한 화면입니다.

        public StudyPage()
        {
            Content = new StackLayout
            {
                Children = {
                    new Label { Text = "Welcome to Xamarin Forms!" }
                }
            };
           
            Padding = new Thickness(0, 20, 0, 0);
        }

이제 실행해 봅니다.

단, UWP 프로젝트는 먼저 배포를 해야합니다.

아래는 실행 결과 입니다.

안드로이드 애뮬과 UWP 앱에 글자가 잘 표시된 걸 볼수 있습니다.

 

어플을 만들면서 DB 를 어떤걸로 쓸지 고민하다가

가장 가벼운? SQLite 를 쓰기로 했습니다. 우선 이전 포스팅에도 있지만 (http://kjcoder.tistory.com/27)

Xamarin 홈페이지에 가면 예시가 잘나와 있습니다.

예시를 가지고 직접 코딩한 내용을 공유해 보고자 합니다.

 

1. 사전 준비

SQLite 를 사용하기 위해서 당연히 SQLite 관련 라이브러리를 추가해야합니다.

NuGet 패키지 관리로 들어가 아래 두항목을 설치합니다.

첫번째껀 SQLite 라이브러리 이며

두번쨰껀 SQLite 를 사용하기 편하게하는 라이브러리입니다.

참조에 아래처럼 라이브러리가 추가되었으면 됩니다.

 

2. Database 생성

DB Browser 이용하여 Database 를 만드는 방법도 있지만 어플을 배포할때 DB 파일을 같이 배포하기 번거롭습니다.

그래서 직접 어플실행시 Database 파일을 만들어야 합니다.

방식은 간단합니다. 특정경로의 파일명을 가지고 Create 하면됩니다.

string DBPath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), "SMSConvey.db");

SqliteConnection.CreateFile(DBPath);

위처럼 하면 일단 Database 파일은 만들어 진것입니다.

당연히 있는데 또 만들면 에러가 발생되니 만들기 전 해당 파일이 존재하는지 확인하는건 필수입니다.

 

3. Table 생성

이제 테이블을 생성합니다. 테이블을 생성하기 위해선 테이블 구조체를 정의 해야합니다.

    public class DB_Group
    {
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }
        public string GroupName { get; set; }
     }

보시면 아시겠지만 ID 는 PK 로 지정되었으며 자동 증가 입니다.

PK 가 반드시 존재해야합니다.

var connection = new SQLiteConnection(DBPath);
{
    connection.CreateTable<DB_Group>();

위처럼 하면 테이블이 생성됩니다.

너무 간단해서 별로 할말이 없군요;

 

4. 데이터 편집

데이터 입력도 간단합니다. 정의한 구조에 값을 셋팅하고 처리하면됩니다.

DB_Group group = new DB_Group();

group.GroupName = "testGroup"; 

var connection = new SQLiteConnection(DBPath);
{

   // 추가합니다.
   db.Insert(group);

   // 수정합니다.
   db.Update(group);

   // 삭제합니다.
   db.Delete(group);


}

 

5. 데이터 가져오기

데이터가 저장되었으면 가져오기도 해야합니다.

가져오는건 키기준으로 가져오는게 기본이니 키 기준으로 가져와 보겠습니다.

int key = 1;

var connection = new SQLiteConnection(DBPath);
{

   var query = db.Table<DB_Group>();

   DB_Group oneData = query.Where(c => c.ID == key).FirstOrDefault(); // 단일값

   List<DB_Group> multiData = query.ToList(); // 여러값

}

위 내용은 가장 기본이고 가장 기초적인 내용입니다.

당연히 비동기로 동작할수 있도록 코딩도 가능합니다.

다음 포스트에서 비동기 동작을 알아보도록 하겠습니다.

 

https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/

 

결과는 아래와 같다.

시간은 millisecond 단위.


millisecond CPU Memory Disk
Count Android Xamarin Android Xamarin Android Xamarin
평균 249.5 147.5 102.2 27 7708.1 12753.7
1 240 137 97 24 8321 13701
2 227 143 109 27 8048 13430
3 257 148 85 26 7737 13564
4 281 161 184 62 7792 13614
5 234 153 94 31 7713 13284
6 270 149 89 17 7524 11229
7 253 185 92 21 7471 12094
8 252 125 102 28 7889 12344
9 250 133 89 16 7318 12031
10 231 141 81 18 7268 12246



결론,

Cpu, Memory 속도는 Xamarin 이 빠르고

Disk 는 Android 가 빠르다


백만을 천만으로 했을때

Cpu 는 위 결과와 동일하게 Xamarin  이 두배 정도 빠르며

Memory 테스트는 Xamarin 으로 했을때는 결과가 나오는데 Android 로는 뻗어버린다.;

Disk 는 용량이 버티질 못할것 같아서 테스트 못했다.

 

테스트 apk 파일은 아래에...

AndroidTest1-debug-unaligned.apk

XamarinTest1.XamarinTest1-Signed.apk

비교파일.xlsx

 

이전에 만든 Tool Bar 에 메뉴를 넣어보겠습니다.

이전게시글(http://kjcoder.tistory.com/169)

 

1. 우선 메뉴에 사용될 아이콘들을 가져옵니다.

https://material.io/icons/

여기로 가면 쓸만한 아이콘들이 많이 있습니다.

drawable.zip

여기서 다루게될 아이콘들의 모음입니다.

원래 검은색인데 회색으로 변경하였습니다.

일단 준비는 끝났고 위 아이콘들을 drawable 폴더에 추가합니다.

 

2. 메뉴를 만듭니다.

Resource 폴더 하위에 menu 폴더를 하나만들고 xml 파일을 추가합니다. top_menu.xml 로 만듭니다. (이름은 맘대로)

내용은 아래와 같습니다.

<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item
       android:id="@+id/menu_Add"
       android:icon="@drawable/ic_add_black_24dp"
       android:showAsAction="ifRoom"
       android:title="추가" />
  <item
       android:id="@+id/menu_Advanced"
       android:showAsAction="never"
       android:title="Visit Site" />
</menu>

첫번째 메뉴는 추가 메뉴입니다. + 모양의 아이콘으로 보여지게됩니다.

두번째 메뉴는 아이콘이 없는 환경 설정 메뉴로 popup 메뉴를 뜨게 할수 있습니다.

* showAsAction="ifRoom" => TollBar 공간이 있으면 메뉴 항목이 표시됩니다.

* showAsAction="never" => 환경설정 메뉴항목이 설정되는 곳으로 세개의 수직점으로 나타납니다.

미리 보기

 

3. 메뉴를 보이도록 합니다.

메뉴가 추가될 화면의 Activity 에 아래 코딩을 추가합니다.

public override bool OnCreateOptionsMenu(IMenu menu)
{
    MenuInflater.Inflate(Resource.Menu.top_menus, menu);
    return base.OnCreateOptionsMenu(menu);
}

OnCreateOptionsMenu 메서드에서 메뉴 리소스를 지정할수 있게 합니다.

 

4. 메뉴 이벤트를 연결합니다.

public override bool OnOptionsItemSelected(IMenuItem item)
{
    Toast.MakeText(this, "Action selected: " + item.TitleFormatted, ToastLength.Short).Show();
    return base.OnOptionsItemSelected(item);
}

사용자가 메뉴항목을 클릭하면 OnOptionsItemSelected 메서드를 호출하고 선택한 메뉴 항목을 전달합니다.

여기서 메뉴 Action 처리를 할수 있습니다.

최종화면은 아래와 같이 나타납니다.

 

 

 

 

+ Recent posts