rksoftware

Visual Studio とか C# とかが好きです

Xamarin で素の Activity と Forms とで画面遷移する

Xamarin.Forms は複数ページのアプリを作れますが、その実現方法は (Android の場合) 一つの Activity 上でビュー表示を切り替えるシングル Activity アプリです。つまり根っこに Activity がいるわけです。それならその Activity を他の Activity から起動したり逆に他の Activity を起動したりできるかもしれません。

ということで試してみました。

■ 素の Activity と Forms の Activity を作る

※リソースファイルなどは省略します。

素の Activity (起動 Activity) 例

まず素の Activity を作ります。今回は素のアクティビティを最初に表示される Activity としてみました。

[Activity(Label = "@string/app_name", MainLauncher = true, Theme = "@style/AppTheme.NoActionBar")]
public class MainActivity : AppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        // ボタンタップで Forms のビューに遷移
        var button = FindViewById<Button>(Resource.Id.button1);
        button.Click += (sender, arg) =>
            StartActivity(new Android.Content.Intent(this, typeof(FormsActivity)));

        // 遷移時に使用する Context を雑に確保
        NativeNavigation.SetContext(this);
    }
}

基本はボタンのタップで、Forms の Activity を起動するコードがあるだけです。
あと、Forms での画面遷移を雑に実装するために、Activity を取っておく処理が最後にあります。

Forms の Activity 例

Forms の Activity は何の変哲もないただの Xamarin.Forms の Activity です。

[Activity(Label = "FormsActivity", Theme = "@style/AppTheme.NoActionBar")]
public class FormsActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

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

Forms のページ 例

Xamarin.Forms のページです。DependencyService で Android の画面遷移を呼ぶようにしてみました。

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FormsMainPage : ContentPage
{
    public FormsMainPage()
    {
        InitializeComponent();

        // ネイティブのビューに遷移
        button2.Clicked += (sender, arg) =>
            DependencyService.Get<INativeNavigation>().GoToNext();
    }
}

DependencyService 例

public interface INativeNavigation
{
    // ネイティブのビューに遷移
    void GoToNext();
}
using Android.Content;
using Namespace;

[assembly: Xamarin.Forms.Dependency(typeof(NativeNavigation))]
namespace Namespace
{
    class NativeNavigation : Core.INativeNavigation
    {
        static Context _context;
        public static void SetContext(Context context) => _context = context;
        static Context Context => _context;

        public void GoToNext() =>
            Context.StartActivity(new Intent(Context, typeof(MainActivity)));
    }
}

■ 実行

ボタンのタップで 素の Activity → Forms の Activity → 素の Activity ... と遷移できました。

こんなことをして良いものなのか、この経験が生きる日がいずれ来るのか分かりませんが、もしかしたら Xamarin に限らず何かでこの経験に救われる日が来るかもしれません。
来ない気がしますけれど。