かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Xamarin.AndroidでReactivePropertyを使いやすくするライブラリを試作してみた

とりあえず。

以下のようなVMがあったとして

using Codeplex.Reactive;
using System;
using System.Reactive.Linq;

namespace App15
{
    public class MainPageViewModel
    {
        public ReactiveProperty<string> Input { get; private set; }
        public ReactiveProperty<string> Output { get; private set; }

        public ReactiveCommand ClearCommand { get; private set; }

        public MainPageViewModel()
        {
            this.Input = new ReactiveProperty<string>();

            this.Output = Observable.Merge(
                this.Input.Where(x => string.IsNullOrEmpty(x)).Select(_ => ""),
                this.Input.Where(x => !string.IsNullOrEmpty(x)).Select(x => x.ToUpper()))
                .ToReactiveProperty();

            this.ClearCommand = new ReactiveCommand();
            this.ClearCommand.Subscribe(_ => this.Input.Value = "");
        }
    }
}

こんな感じでActivityとつなぐことができます。

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Codeplex.Reactive.Extensions;
using ReactiveProperty.XamarinAndroid;
using ReactiveProperty.XamarinAndroid.Extensions;

namespace App15
{
    [Activity(Label = "App15", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        private readonly MainPageViewModel viewModel = new MainPageViewModel();

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

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

            // TwoWay binding
            this.SetBinding(
                // 対象のID
                Resource.Id.EditTextInput,
                // 対象のプロパティ
                (EditText x) => x.Text,
                // ソースのReactiveProperty
                this.viewModel.Input,
                // 更新タイミングのIO<Unit>
                (EditText x) => x.TextChangedAsObservable().ToUnit());

            // OneWay binding
            this.SetBinding(
                // 対象のID
                Resource.Id.TextViewOutput,
                // 対象のプロパティ
                (TextView x) => x.Text,
                // ソースのReactiveProperty
                this.viewModel.Output);

            // Command binding
            this.FindViewById<Button>(Resource.Id.ButtonClear)
                .ClickAsObservable()
                // IO<T>の発火でコマンドをキックする
                .SetCommand(this.viewModel.ClearCommand);
        }
    }
}

コレクション系は、前につくったライブラリのソースをごそっと持ってきたので、各種コレクションに対してToAdapterでIListAdapterがゲットできます。

Xamarin AndroidでIListやObservableCollectionをListViewに表示する - かずきのBlog@hatena

主な機能

  • コレクションをIListAdapterに変換するToAdapter拡張メソッド。
  • SetBindingメソッドによる単方向・双方向データバインド
  • SetCommandによるIObservableとReactiveCommandの接続
  • Viewを継承したクラスほぼ全てのイベントに対してEventNameAsObservableの拡張メソッド

です。さくっと作った割には少し気に入ってるので手を入れていってみようかな。

導入

NuGetに放流してあります。

NuGet Gallery | ReactiveProperty.XamarinAndroid 0.0.2