Help us understand the problem. What is going on with this article?

Visual Studio for Mac での Xamarin.Forms (iOS/ Android アプリ開発) 入門 02 : 新規作成したプロジェクトの構成を見てみる & 簡単な画面更新してみる

今回は、どんなファイルが生えたのか目を通すのと、少し UI をいじってみるのをやりましょう。

前回の記事『Visual Studio for Mac での Xamarin (iOS/ Android) 入門 01 : ハローワールド (新規作成、エミュレータ作成、アプリ実行)

この記事の目標

  • 自動生成されたプロジェクトの中を見て、どんなファイルがあるか確認する
  • 重要なファイルについてはコードに目を通す。
    • App.xaml:Xamarin.Forms の最初のエントリーポイント。ここで MainPage.xaml が呼ばれている
    • MainPage.xaml:アプリの最初に出て来る画面の UI が記述されている
    • MainActivity.cs:Android アプリ起動時に内部的に最初に呼ばれる人
    • AppDelegate.cs:iOS アプリのライフサイクルを管理している人
    • AndroidManifest.xml:Android アプリ設定ファイル
    • Info.plist:iOS アプリ設定ファイル
  • アプリの UI を定義している XAML ファイルを編集し、iOS/ Android アプリの画面を編集する

Reference

プロジェクトの構成

VS for Mac の左のソリューションバーを見てみると、
この、新規作成したプロジェクト (ソリューション) の中には
3 つのプロジェクトが含まれていることが分かります

image.png

プロジェクト名 説明
1 TestApp 共通コード。全コードの 9 割くらいがここに入る。画面 UI 記述などもここ
2 TestApp.Android Android 版の固有のコードの置き場所
3 TestApp.iOS iOS 版の固有のコード置き場

それぞれ見てみましょう

共通プロジェクト TestApp

一番上に生えた TestApp のツリーを開くと、このようになっています。

image.png

XAML (ザムル) とは、Extensible Application Markup Language の略で、アプリ UI などを定義するための XML ベースのマークアップ言語のことです。

App クラス (App.xaml + App.xaml.cs)

App.xaml のツリーを開くと、コードビハインドの App.xaml.cs が現れます。

image.png

App.xamlApp.xaml.cs 両方(ペア)で、
ひとつの App クラスを定義している構成になっています。

XAML で記述した GUI に対して、 C# (など) でイベント処理を記述することができますが、そのときに、その GUI 定義ファイル (.xaml) と イベント記述のファイル (.cs) を分けて書くことができます。分けて書いているだけなので、ふたつはペアとして存在しています。

ちなみに、こうやって GUI のイベント処理を別ファイルに分けて書くことを コードビハインド(code-behind)と呼びます。

この App クラスが、Xamarin.Forms のエントリーポイントとなります。

App.xaml.cs

コードビハインドの App.xaml.cs を見てみましょう。

App.xaml.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace TestApp
{
    public partial class App : Application
    {
        // Xamarin.Forms のエントリーポイント
        public App()
        {
            // App.xaml で定義された内容を読み込む
            InitializeComponent();
            // アプリのメインページとして、MainPage クラスのインスタンスを設定している
            MainPage = new MainPage();
        }

        protected override void OnStart()
        {
        }

        protected override void OnSleep()
        {
        }

        protected override void OnResume()
        {
        }
    }
}

MainPage.xaml

この中の XAML (ザムル) ファイル MainPage.xaml に、アプリ起動時の画面の定義が書いてあります。

(正確に言うと、アプリのエントリーポイントは App クラスで、そこで起動時の画面を MainPage と指定しているから最初の画面として MainPage.xaml が呼ばれています。)

MainPage.xaml の中は、こうなっています。

MainPage.xaml
<?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:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
             x:Class="TestApp.MainPage">
    <StackLayout>
        <!-- Place new controls here -->
        <Label
            Text="Welcome to Xamarin.Forms!"
            HorizontalOptions="Center"
            VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

ContentPage の中に、
StackLayout (縦に色々詰めるレイアウト雛形) が入っていて、
その中にラベル Label が一つ、中央寄せに配置されている、という感じですね。

で、そのラベルの中に Text="Welcome to Xamarin.Forms!" と定義されているので、
アプリを実行したときに 「Welcome to Xamarin.Forms!」 と表示されたのですね。

ためしにここを「Xamarin.Forms にようこそ」などと変えて
もう一度実行してみると、
iOS/ Android アプリ両方が変更されます。

image.png

ひとつのソースコードを変更したら、それが iOS/ Android 両方に反映されるので、
めちゃ便利ですね!
iOS 用、Android 用でコードが分かれることもなく。

今回は表示テキストを変更するだけでしたが、
当然、もっともっと複雑なことがたくさんできるわけで、
それを両方の OS 用に同時にクロスプラットフォーム開発できて便利という話になるわけです。

Android 固有プロジェクト TestApp.Android

次は Android 固有プロジェクト TestApp.Android の中を見てみましょう。
iOS 側からは呼ばれず、Android での実行時にのみ呼ばれるメソッドなどが入っています。

TestApp.Android のツリーを開くと、
いくつか中身が入っているのが見えますが、
この中に、Android ネイティブ開発者には見慣れた MainActivityAndroidManifest.xml というのが見えます。

image.png

MainActivity.cs

この MainActivity.cs を開いて、中身を見てみましょう

MainActibity.cs
using System;

using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace TestApp.Droid
{
    [Activity(Label = "TestApp", Icon = "@mipmap/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 savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            // Xamarin 周り初期化
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

OnCreate() は、Android アプリのライフサイクルの中で、このアクティビティが立ち上がったときにまず呼ばれるメソッドです。
Android アプリ開発者なら Java や Kotlin で何度も見ているものですね。それが C# で書かれているだけです。

その OnCreate() の中で、Xamarin.Forms の初期化などが呼ばれて走っているだけとなります。

AndroidManifest.xml

次は、設定ファイル AndroidManifest.xml も見てみましょう。
これも、Android アプリ開発者なら 何度も見ているファイルですね。
このマニフェストファイルにアプリの基本的な設定など(アプリアイコンどうするとか最初に呼ばれるアクティビティはどれとか)が書かれていて、これがないとアプリとして出せない重要なファイルです。

image.png

実際は、AndroidManifest.xml は(拡張子の通り)XML で書かれているのですが、
VS for Mac は、それの viewer の機能があるので、上のスクショのように、いい感じに表示してくれています。(昔は XML 丸出しだったんだよ(2014 年からずっと Xamarin やってる古株なみの感想))

iOS 固有プロジェクト TestApp.iOS

次は iOS 固有プロジェクト TestApp.iOS の中を見てみましょう。
Android からは呼ばれず iOS のみの処理が書かれています。

image.png

iOS アプリ開発者なら何度も見ているファイルがいくつかありますね!

AppDelegate.cs

AppDelegate は、iOS アプリのライフサイクルを定義している人ですが、
ここでは「アプリが起動 (FinishedLaunching()) したら Xamarin.Forms を初期化する」という処理が呼ばれているだけとなります。

AppDelegate.cs
using System;
using System.Collections.Generic;
using System.Linq;

using Foundation;
using UIKit;

namespace TestApp.iOS
{
    // iOS アプリのライフサイクルを管理するクラス AppDelegate
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        // アプリが起動したときに呼ばれる
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            // Xamarin.Forms 初期化
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());

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

アプリが起動したときに呼ばれる FinishedLaunching() の中で、Xamarin.Forms の初期化などが呼ばれて走っているだけとなります。

Next Step

色々公式チュートリアルをやってみるのが良さそうですね!

Hot Reload もいいぞ

ちなみに、Xamarin.Forms の XAML 保存時にリアルタイムで UI 更新してくれる、Hot Reload 機能もオススメです。

YouTube 動画 (ちょまどチャンネル)
XAML Hot Reload for Xamarin.Forms (Xamarin.Forms の XAML ホットリロード)

この 90 秒動画見ていただけたらなんとなくどんなものかつかめると思います

chomado
ITエンジニア兼マンガ家の千代田まどか (ちょまど) です。Microsoft 社の Cloud Developer Advocate として、デベロッパーコミュニティの支援を行っています。松屋とゲームとアニメが好きです
https://chomado.com/
microsoft
マイクロソフトのメンバーが最新の技術情報をお届けします。Twitterアカウント(@msdevjp)やYouTubeチャンネル「クラウドデベロッパーちゃんねる」も運用中です。
https://aka.ms/MSFT-Docs-JPN
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした