21
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

KotlinでData Bindingをする - Observable Object編

Posted at

前提

基礎編の続きとして、Observable Objectを用いたバインドをKotlinで書いてみます。
すでにGradleの設定が済んでおり、Kotlinでバインドができるようになっていることが前提です。

モデルを作成する

シンプルなモデルを作成

今回はObservable Objectの例なのでData Classではなく、普通のクラスを使います。これはObservable Objectを用いる場合は他クラスの継承や、アノテーションを付ける必要があるためです。

とりあえずモデルはシンプルに以下のような感じです。

OrderViewModel.kt
class OrderViewModel(val book: Book) {
    val orderedBook: Book = book
    var count: Int = 0 // あとで変更するので、 var で定義
}

なお、Bookクラスなどは基礎編のものを流用しています。

BaseObservableを継承する

このままではObservableにはなりませんので、BaseObservableを継承します。

OrderViewModel.kt
class OrderViewModel(val book: Book): BaseObservable() {
    val orderedBook: Book = book
    var count: Int = 0
}

変更の通知を行うための設定をする

ここがキモとなります。
行うべきことは、以下の2点です。

  1. プロパティのゲッターにBindableアノテーションの付与
  2. セッターで変更の通知を行う

これらは公式のData Binding Libraryのドキュメントにある下記の記述がソースです。

This is done by assigning a Bindable annotation to the getter and notifying in the setter.

今回はカウント(count)をObserveするために以下のようになります。

アノテーションの付け方やセッターの実装がKotlin特有ですが、ドキュメントを見れば理解できます。ページ下部の参考にリンクを置いておきます。
なお下記コードでBRを使っていますが、これは自動で作られます。

OrderViewModel.kt
class OrderViewModel(val book: Book): BaseObservable() {
    val orderedBook: Book = book

    @get:Bindable
    var count: Int = 0
        set(value) {
            field = value  // 値をセット
            notifyPropertyChanged(BR.count) // 変更を通知
        }
}

これでモデル側の実装は完了です。

レイアウトファイルでバインドを指示する

これはこれまで通りです。今回はcountをバインドします。
アクティビィとレイアウトは以下のようになります。

MainActivity.kt
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // バインドするデータを作成。今回は手で作成
        val author1 = Author(name = "一郎")
        val author2 = Author(name = "次郎")
        val book = Book(title = "とても良い本", price = 1000, authors = listOf(author1, author2))
        var order = OrderViewModel(book)

        val mainActivityBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        mainActivityBinding.order = order
    }
activity_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="order"
            type="com.example.kotlinsample.viewmodel.OrderViewModel" />
    </data>
    ...
        <TextView
            ....
            android:text="@{String.valueOf(order.count)}"
            .... 
        />
</layout>

バインドした値を変更してみる

これで完了ですが、動作上はただのデータバインドです。
ここで、プログラムからBindableにしたcountプロパティを変更してみると、動作が確認できます。
適当にボタンを用意して、クリックでcountの値を増減させます。

MainActivity.kt
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // バインドするデータを作成。今回は手で作成
        val author1 = Author(name = "一郎")
        val author2 = Author(name = "次郎")
        val book = Book(title = "とても良い本", price = 1000, authors = listOf(author1, author2))
        var order = OrderViewModel(book)

        val mainActivityBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        mainActivityBinding.order = order

        // プラスとマイナスボタンは適宜用意し、それぞれのクリックでcountを増減させる
        (findViewById(R.id.plusButton) as Button).setOnClickListener { v ->
            order.count += 1
        }

        (findViewById(R.id.minusButton) as Button).setOnClickListener { v ->
            order.count -= 1
        }
    }

これで実行すると、プラスとマイナスのそれぞれのボタンのクリックで、カウントのラベルが増減することが確認できます。

参考

21
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?