Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

XamarinのAndroidアプリでReactivePropertyを使う 2016年版

$
0
0

随分昔に書いてますね。

blog.okazuki.jp

最近は事情も変わったので改めて書いてみようと思います。

ReactivePropertyは?

Reactive ExtensionsをベースにしたMVVMの支援ライブラリです。

blog.okazuki.jp

Xamarinでも使えるの?

Xamarin.AndroidとXamarin.iOSとXamarin.Formsに対応しています!ここでは、Xamarin.Androidでの使い方を紹介したいと思います(Mac持ってない)。因みに、ここで紹介するのと同じ感覚でiOSアプリでも使えるので興味を持った人は試してみてください!

Hello world的なもの

新規作成したときに作成されるカウントアップアプリをReactivePropertyを使って再現したみたいと思います。

プロジェクトの作成

Blank App(Android)を作成します。そして、NuGetからReactivePropertyを参照に追加します。

Counterクラスの作成

カウンターのクラスを作ります。普通のC#のクラスです。

using System.ComponentModel;

namespace CounterApp
{
    publicclass Counter : INotifyPropertyChanged
    {
        publicevent PropertyChangedEventHandler PropertyChanged;

        privateintvalue;

        publicint Value
        {
            get { returnthis.value; }
            privateset
            {
                this.value = value;
                this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Value)));
            }
        }

        publicvoid Increment()
        {
            this.Value++;
        }
    }
}

ViewModelの作成

次にMainActivityのViewModelになるMainActivityViewModelクラスを作成します。

using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System;
using System.Linq;
using System.Reactive.Linq;

namespace CounterApp
{
    publicclass MainActivityViewModel
    {
        // Modelprivate Counter Model { get; } = new Counter();

        // Viewへ公開するインターフェースpublic ReadOnlyReactiveProperty<string> CounterValue { get; }

        public ReactiveCommand IncremantCommand { get; }

        public MainActivityViewModel()
        {
            // Counter.Valueを監視して文字列化this.CounterValue = this.Model
                .ObserveProperty(x => x.Value)
                .Select(x => x.ToString())
                .ToReadOnlyReactiveProperty();

            // インクリメントするコマンドthis.IncremantCommand = new ReactiveCommand();
            this.IncremantCommand.Subscribe(_ => this.Model.Increment());
        }
    }
}

ここまでは、普通のC#とReactivePropertyを使ったプログラミングです。

Vの作成

次にMainActivityに行きます。ReactivePropertyではAndroidのViewとバインドするための拡張メソッドとしてSetBindingというメソッドを提供しています。これを使うとコントロールのプロパティとReactivePropertyをバインドすることが出来ます。

また、コントロールのイベントをIObservableに変換したあとSetCommand拡張メソッドでコマンドを設定することで、コントロールのイベントとCommandを紐づけることが出来ます。

コードを書いてみましょう。

using Android.App;
using Android.OS;
using Android.Widget;
using Reactive.Bindings;
using System.Reactive.Linq;

namespace CounterApp
{
    [Activity(Label = "CounterApp", MainLauncher = true, Icon = "@drawable/icon")]
    publicclass MainActivity : Activity
    {
        private MainActivityViewModel ViewModel { get; } = new MainActivityViewModel();

        protectedoverridevoid 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
            var button = FindViewById<Button>(Resource.Id.MyButton);

            // ButtonのTextとバインド
            button.SetBinding(
                x => x.Text,
                this.ViewModel.CounterValue);

            // ButtonのClickイベントとバインド
            Observable.FromEventPattern(button, nameof(Button.Click))
                .SetCommand(this.ViewModel.IncremantCommand);
        }
    }
}

axmlに書いてバインドはできないのでごめんなさい。でもコードでも割と直感的に書けるかなと思ってます。

実行すると

以下のようになります。

f:id:okazuki:20160406203357p:plain

気になった人は

因みに公式でしっかり書いてるのはこちら。 コレクションのバインドもサポートしています。

github.com

Xamarin.Formsで使ってくれてる人もいる

ちゃんとXamarin.Formsでも使えるよっていうことで!

tamafuyou.hatenablog.com


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>