Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
Xamarin逆引きTips

Xamarin逆引きTips

Xamarin.AndroidでActivityとXamarin.Formsを併用するには?

2014年6月18日

iOSの場合と同じように、Androidアプリの一部の画面に、Xamarin.Formsを利用する方法を解説する。また、iOSとの挙動の違いやフラグメントとの併用についても言及する。

奥山 裕紳(@amay077
  • このエントリーをはてなブックマークに追加

 Xamarin.iOSの場合と同様、Xamarin.Android開発でも一部の画面にXamarin.Formsを利用可能だ。今回はその方法を解説する。

シナリオ

 下の図のようなActivityによる画面1、画面2、画面3があり、画面2にのみXamarin.Formsを適用する。

図1 シナリオ

1Androidプロジェクトを作成する

 「Tips:Xamarin.iOSでStoryboardとXamarin.Formsを併用するには?」で作成した「FomrsInNatives」ソリューションにAndroidプロジェクトを追加する。ソリューションツリーの右クリックメニューから[追加]-[新しいプロジェクトを追加]とし、[C#]-[Android]-[Android Ice Cream Sandwich Application]を作成する。プロジェクト名は「FormsInNativeViews.Android」とする。

 作成されたプロジェクト内のMainActivity.csファイルを画面1として使用するので、画面2となるSecondActivity.csファイル、画面3となるThirdActivity.csファイルを([Android Activity]テンプレートを使って)追加する。

 MainActivity.csファイルでは、下記のコードに示すように、ひな型コードとして生成された「ボタンを押したときの処理」を修正して(=太字部分)、SecondActivityへ移動するようにする。

C#
……省略……
[Activity(Label = "FormsInNativeViews.Android", MainLauncher = true)]
public class MainActivity : Activity
{
  protected override void OnCreate(Bundle bundle)
  {
    base.OnCreate(bundle);

    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.Main);

    // Get our button from the layout resource,
    // and attach an event to it
    Button button = FindViewById<Button>(Resource.Id.myButton);
    
    button.Click += delegate
    {
      StartActivity(typeof(SecondActivity));
    };
  }
}
SecondActivityへ移動するように修正したコード(MainActivity.cs)

 SecondActivityは後で実装する。次にThirdActivityは、遷移したことが分かるようにTextViewを配置しておく(=太字部分)。下記のコードはその実装例である。

C#
……省略……
[Activity(Label = "ThirdActivity")]
public class ThirdActivity : Activity
{
  protected override void OnCreate(Bundle bundle)
  {
    base.OnCreate(bundle);

    AddContentView(
      new TextView(this)
      {
        Text = "This is ThirdActivity",
        TextSize = 20,
        Gravity = GravityFlags.Center
      },
      new ViewGroup.LayoutParams(
        ViewGroup.LayoutParams.MatchParent,
        ViewGroup.LayoutParams.MatchParent));
  }
}
遷移したことが分かるようにTextViewを配置するコード(ThirdActivity.cs)

2AndroidプロジェクトにXamarin.Formsを利用するための設定を行う

 ソリューションツリーのFormsInNativeViews.Androidプロジェクト内の[参照]の右クリックメニューから[参照アセンブリの編集]を選択し、表示されるダイアログで[Projects]タブを選択。続いて[FormsInNativeViews]にチェックを入れて[OK]ボタンを押す(図2)。

図2 プロジェクト追加画面

 次に、メニューバーの[プロジェクト]-[Add Packages]を選択する。表示されるダイアログの右上の検索ボックスで「Xamarin.Forms」と入力して検索すると、同名のパッケージが見つかるのでチェックを入れて[Add Packages]ボタンを押す(図3)。

図3 パッケージ追加画面

 ソリューションツリーの[パッケージ]の中に[Xamarin.Forms]が追加されるはずだ。

3ActivityにXamarin.Formsの画面を適用する

 Activityに、Xamarin.Formsの画面(=FormsInNativeViewsプロジェクトのMainPage.cs)を適用するために、SecondActivity.csファイルを以下のように実装する。

C#
 
 
 
 
 
1
 
 
 
 
 
2
 
 
3
 
 
 
 
4
 
 
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using FormsInNativeViews;
……省略……
[Activity(Label = "SecondActivity")]
public class SecondActivity : AndroidActivity
{
  protected override void OnCreate(Bundle bundle)
  {
    base.OnCreate(bundle);

    Forms.Init(this, bundle);

    var page = new MainPage();
    page.GotoThirdButton.Clicked += (sender, e) =>
    {
      StartActivity(typeof(ThirdActivity));
    };

    this.SetPage(new NavigationPage(page));
  }
}
ActivityにXamarin.Formsの画面を適用するコード(SecondActivity.cs)

 Xamarin.Formsを利用するActivityは、ベースクラスをAndroidActivityに変更する(1)。

 次にFormsの初期化を行うが(2)、ActivityBundleを引数とすることから、画面ごとに初期化が必要なようだ。

 3MainPage内のボタンが押された時の実装方法はiOSと同じだが、もちろんここは次のActivityへ遷移するネイティブの実装を行う。

 最後に、4SetPageメソッドでMainPageをコンテンツとして設定する。NavigationPageを挟まないとタイトルバー(=AndroidネイティブでいうActionBar)が表示されないので注意が必要だ。

4実行する

 作成したプロジェクトを実行すると、図4のようになる。

図4 実行画面

 注目したいのが、SecondActivityのタイトルが、ネイティブ側で設定したものでなく、MainPage.csファイルで設定した「Page by Xamarin.Forms」となっていることだ。iOSではStoryboardで設定したタイトルが適用されたが、プラットフォームにより微妙な違いがあるようだ。

まとめ

 Xamarin.Formsの画面(Page)をActivityと共存させる方法を解説した。iOSと同様、画面のコンテンツにXamarin.Formsを利用することで、アプリの一部分を共通化することが可能だ。ただし、画面のタイトルのように、プラットフォームごとに挙動が異なる場合があるので、やはり細かい調整は必要だ。

【コラム】フラグメントとの併用

 Androidでは画面内のUIパーツ群を部品化できる「フラグメント(Fragment)」という仕組みがあるが、現在は、同じ画面内でXamarin.Formsとフラグメントを併用することはできないようだ。フラグメントを利用するためには、Fragmentから派生したクラスを作成し、FragmentManagerクラスにより画面に追加する必要があるが、これらを代替するようなXamarin.FormsのAPIは見つけることができなかった。やはりネイティブの特徴を生かしたアプリを作るならば、素直にネイティブの画面レイアウトを利用した方がよいだろう。

※以下では、本稿の前後を合わせて5回分(第5回~第9回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

Xamarin逆引きTips
5. iOS/Androidの画面レイアウトを共通化するには?(Xamarin.Forms)

Xamarin 3がリリースされた。その新機能として注目されるXamarin.Formsの概要と、基本的な使い方、メリット/デメリットを解説する。Xamarin.Formsを使ってiOS/Android/Windows Phone間で画面レイアウトも共通化しよう。

Xamarin逆引きTips
6. Xamarin.iOSでStoryboardとXamarin.Formsを併用するには?

Storyboardで作成したiOSアプリの一部の画面に、Xamarin.Formsを利用する方法を解説する。

Xamarin逆引きTips
7. 【現在、表示中】≫ Xamarin.AndroidでActivityとXamarin.Formsを併用するには?

iOSの場合と同じように、Androidアプリの一部の画面に、Xamarin.Formsを利用する方法を解説する。また、iOSとの挙動の違いやフラグメントとの併用についても言及する。

Xamarin逆引きTips
8. Xamarin.Formsからプラットフォーム固有の機能を利用するには?(DependencyService利用)

UIを共通化するフレームワーク「Xamarin.Forms」で、「DependencyService」機能を使用してiOS/Androidの各プラットフォーム固有の機能を実装する方法を解説する。

Xamarin逆引きTips
9. Xamarin.Formsでダイアログボックス(とBusyインジケーター)を表示するには?

ダイアログ(=iOSのUIAlertView/AndroidのAlertDialog)や、処理実行中を示すBusyインジケーターを、Xamarin.Formsで表示する方法を解説する。これらは共通のAPIを使って実装できる。

サイトからのお知らせ

Twitterでつぶやこう!