Xamarin.Formsへ動的にXAMLデータをロードする…の手始め

第1回 Xamarin User Group は無事終了。プレゼン資料については後ほど解説を入れるとして、なにかと気になったので、ちょっと手を付けてみました。

Xamarin.Forms を使うとき、Phone の場合は画面が狭いので手打ちで XAML を書いてもなんとかなるのですが、タブレットのように広い画面になった時や、Xcode の autolayout みたいな感じでレイアウトしようとすると手打ち XAML だけだと結構大変です。実行しないとうまくいかないし、懇親会でもレイアウトに苦労している場面もあったりして、

  • エミュレータで実行してみないと、タグの typo が分からない。
  • エミュレータで実行してみないと、レイアウト崩れがわからない。

のは、いかんともしがたいところ。Xamarin.Forms 用のデザイナが出ればいいんですが、暫くは出る様子もないので、なんとかならんかなと。そこに、「プレビューでもあれば便利なのに」とのツイートを見つけました。

なるほど、デザイン自体は大変そうだけど、プレビューだけならなんとかなりそうです。

  1. Xamarin.Froms の XAML を手打ちする。
  2. 更新されたファイルを読み取って、デザイナに描画する。

程度の繰り返しができればよいわけで、そのサイクルが早く回れば try & error も進みそう。で、なにか方法はないかと思って、ひとつ思いついたのが、

  1. デザイン用の XAML を手打ちする。
  2. なんらかの形で iOS/Android のエミュレータにアップ。あるいは、エミュレータからプル。
  3. なんらかの形で、エミュレータ上で XAML を解析して、レイアウトを作成する。

というパターンです。プレビュー自体をエミュレータ内で動かしてしまえばよいのです。

image

幸いにして、Xamarin.Forms の場合は、プラットフォーム共通のレイアウトページとして Xamarin.Forms の ContentPage が用意されています。大抵は PCL で作るんですが、この new ContentPage したものを、iOS/Android のプラットフォーム毎に再構成しています。ならば、この new ContentPage のところをすり替えてしまえば、良いわけで実際、XAML のほうではなくて、コードでちまちまと ContentPage を作っているところを、XAML から作り込めるようにすれば良いわけです。

namespace XFormsPreview
{
    public partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        void OnClickPreview(object sender, EventArgs e)
        {
            // var page = new NewPage();
            string xml = @"<?xml version='1.0' encoding='utf-8' ?>
<Contentpage x:class="XFormsPreview.NewPage" 
xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml
xmlns="http://xamarin.com/schemas/2014/forms"> <Stacklayout> <Label Text="New Page"> <Button Text="click me"> </Stacklayout> </Contentpage> "; var page = ContentPageXaml.LoadXaml(xml); this.Navigation.PushAsync(page); } } }

こんな風に文字列で XAML を設定して LoadXml すると ContentPage ができるようにします。ここは F# の Type Provider と似た感じですね。

まだテスト中なので、XAML の文字を埋め込んでいますが、これをエミュレータの動いている PC から XAML ファイルをダウンロードできるようにすれば、XAML の修正とプレビューのサイクルが早くなります。大まかの動きの目途は立ったので、あとはちまちまと Xmarin.Forms のコントロールを移し替えていきます。車輪の再発明ような感じもするし、既にあるような気もするし、本格的なデザイナが出るまでの短い間という訳でもあるけど、ひとまず、一通り動くところまで作ってみる予定。

カテゴリー: C#, Xamarin パーマリンク